import { Injectable } from "@nestjs/common"; import { PrismaService } from "src/prisma/prisma.service"; import { module_list, Modules } 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/employee.utils"; import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto"; import { toKeysFromBoolean } from "src/common/utils/boolean-utils"; @Injectable() export class EmployeesGetService { constructor( private readonly prisma: PrismaService, private readonly emailResolver: EmailToIdResolver, ) { } async findListEmployees(): Promise[], string>> { const employee_list = await this.prisma.employees.findMany({ select: { user: { select: { first_name: true, last_name: true, email: true, }, }, supervisor: { select: { user: { select: { first_name: true, last_name: true, }, }, }, }, is_supervisor: true, job_title: true, company_code: true, external_payroll_id: true, first_work_day: true, last_work_day: true, schedule_preset_id: true, } }).then(rows => rows.map(r => ({ first_name: r.user.first_name, last_name: r.user.last_name, email: r.user.email, 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}`, is_supervisor: r.is_supervisor, supervisor_full_name: `${r.supervisor?.user.first_name} ${r.supervisor?.user.last_name}`, first_work_day: toStringFromDate(r.first_work_day), last_work_day: r.last_work_day ? toStringFromDate(r.last_work_day) : null, preset_id: r.schedule_preset_id ?? undefined, }))); return { success: true, data: employee_list }; }; async findOwnProfile(email: string): Promise, string>> { const user_id = await this.emailResolver.resolveUserIdWithEmail(email); if (!user_id.success) return { success: false, error: 'INVALID_USER' }; const existing_profile = await this.prisma.employees.findUnique({ where: { user_id: user_id.data }, select: { user: { select: { first_name: true, last_name: true, email: true, phone_number: true, residence: true, }, }, first_work_day: true, company_code: true, job_title: true, external_payroll_id: true, is_supervisor: true, schedule_preset_id: true, supervisor: { select: { id: true, user: { select: { first_name: true, last_name: true, }, }, }, }, }, }); if (!existing_profile) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }; const company_name = toStringFromCompanyCode(existing_profile.company_code); return { success: true, data: { first_name: existing_profile.user.first_name, last_name: existing_profile.user.last_name, email: existing_profile.user.email, supervisor_full_name: `${existing_profile.supervisor?.user.first_name} ${existing_profile.supervisor?.user.last_name}`, company_name: company_name, job_title: existing_profile.job_title ?? '', external_payroll_id: existing_profile.external_payroll_id, is_supervisor: existing_profile.is_supervisor, phone_number: existing_profile.user.phone_number, residence: existing_profile.user.phone_number, first_work_day: toStringFromDate(existing_profile.first_work_day), preset_id: existing_profile.schedule_preset_id ?? undefined, }, }; }; async findOneDetailedProfile(email: string, employee_email?: string): Promise> { const account_email = employee_email ?? email; const user_id = await this.emailResolver.resolveUserIdWithEmail(account_email); if (!user_id.success) return { success: false, error: 'INVALID_USER' }; const employee = await this.prisma.employees.findUnique({ where: { user_id: user_id.data }, select: { user: { select: { first_name: true, last_name: true, email: true, phone_number: true, residence: true, user_module_access: { select: { dashboard: true, employee_list: true, employee_management: true, personal_profile: true, timesheets: true, timesheets_approval: true, }, }, }, }, supervisor: { select: { user: { select: { first_name: true, last_name: true, }, }, }, }, job_title: true, company_code: true, first_work_day: true, last_work_day: true, external_payroll_id: true, is_supervisor: true, schedule_preset_id: true, schedule_preset: { select: { id: true, } } } }); if (!employee) return { success: false, error: `EMPLOYEE_NOT_FOUND` }; if (!employee.user) return { success: false, error: 'USER_NOT_FOUND' }; let module_access_array: Modules[] = []; if (employee.user.user_module_access) { module_access_array = toStringFromBoolean(employee.user.user_module_access); } const company_name = toStringFromCompanyCode(employee.company_code); return { success: true, data: { first_name: employee.user.first_name, last_name: employee.user.last_name, email: employee.user.email, residence: employee.user.residence ?? '', phone_number: employee.user.phone_number, company_name: company_name, is_supervisor: employee.is_supervisor ?? false, job_title: employee.job_title ?? '', external_payroll_id: employee.external_payroll_id, employee_full_name: `${employee.user.first_name} ${employee.user.last_name}`, first_work_day: toStringFromDate(employee.first_work_day), last_work_day: employee.last_work_day ? toStringFromDate(employee.last_work_day) : undefined, supervisor_full_name: employee.supervisor ? `${employee.supervisor?.user.first_name} ${employee.supervisor?.user.last_name}` : '', user_module_access: module_access_array, preset_id: employee.schedule_preset_id ? employee.schedule_preset_id : undefined, }, }; }; } const createDefaultModuleAccess = (): Record => module_list.reduce((acc, mod) => { acc[mod] = false; return acc; }, {} as Record); export const toBooleanFromString = (arr?: readonly string[] | null): Record => { const result = createDefaultModuleAccess(); if (!arr || !Array.isArray(arr)) return result; for (const item of arr) { if (typeof item !== 'string') continue; const trimmed = item.trim(); if ((module_list as readonly string[]).includes(trimmed)) { result[trimmed as Modules] = true; } } return result; } export const toStringFromBoolean = (boolean_module_access: Record): Modules[] => { const access_array = Object.entries(boolean_module_access); const allowed_accesses = access_array.filter(([_key, value]) => value === true); return allowed_accesses.map(([key]) => key as Modules); }