193 lines
5.8 KiB
TypeScript
193 lines
5.8 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from 'src/prisma/prisma.service';
|
|
import { CreateEmployeeDto } from '../dtos/create-employee.dto';
|
|
import { UpdateEmployeeDto } from '../dtos/update-employee.dto';
|
|
import { Employees, Users } from '@prisma/client';
|
|
|
|
@Injectable()
|
|
export class EmployeesService {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async create(dto: CreateEmployeeDto): Promise<Employees> {
|
|
const {
|
|
first_name,
|
|
last_name,
|
|
email,
|
|
phone_number,
|
|
residence,
|
|
external_payroll_id,
|
|
company_code,
|
|
first_work_day,
|
|
last_work_day,
|
|
} = dto;
|
|
|
|
return this.prisma.$transaction(async (tx) => {
|
|
const user: Users = await tx.users.create({
|
|
data: {
|
|
first_name,
|
|
last_name,
|
|
email,
|
|
phone_number,
|
|
residence,
|
|
},
|
|
});
|
|
return tx.employees.create({
|
|
data: {
|
|
user_id: user.id,
|
|
external_payroll_id,
|
|
company_code,
|
|
first_work_day,
|
|
last_work_day,
|
|
},
|
|
});
|
|
});
|
|
}
|
|
|
|
findAll(): Promise<Employees[]> {
|
|
return this.prisma.employees.findMany({
|
|
include: { user: true },
|
|
});
|
|
}
|
|
|
|
async findOne(id: number): Promise<Employees> {
|
|
const emp = await this.prisma.employees.findUnique({
|
|
where: { id },
|
|
include: { user: true },
|
|
});
|
|
if (!emp) {
|
|
throw new NotFoundException(`Employee #${id} not found`);
|
|
}
|
|
return emp;
|
|
}
|
|
|
|
async update(
|
|
id: number,
|
|
dto: UpdateEmployeeDto,
|
|
): Promise<Employees> {
|
|
const emp = await this.findOne(id);
|
|
|
|
const {
|
|
first_name,
|
|
last_name,
|
|
email,
|
|
phone_number,
|
|
residence,
|
|
external_payroll_id,
|
|
company_code,
|
|
first_work_day,
|
|
last_work_day,
|
|
} = dto;
|
|
|
|
return this.prisma.$transaction(async (tx) => {
|
|
await tx.users.update({
|
|
where: { id: emp.user_id },
|
|
data: {
|
|
...(first_name !== undefined && { first_name }),
|
|
...(last_name !== undefined && { last_name }),
|
|
...(email !== undefined && { email }),
|
|
...(phone_number !== undefined && { phone_number }),
|
|
...(residence !== undefined && { residence }),
|
|
},
|
|
});
|
|
|
|
return tx.employees.update({
|
|
where: { id },
|
|
data: {
|
|
...(external_payroll_id !== undefined && { external_payroll_id }),
|
|
...(company_code !== undefined && { company_code }),
|
|
...(first_work_day !== undefined && { first_work_day }),
|
|
...(last_work_day !== undefined && { last_work_day }),
|
|
},
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
async remove(id: number): Promise<Employees> {
|
|
await this.findOne(id);
|
|
return this.prisma.employees.delete({ where: { id } });
|
|
}
|
|
|
|
|
|
//archivation function
|
|
async patchEmployee(id: number, dto: UpdateEmployeeDto): Promise<any> {
|
|
//fetching existing employee
|
|
const existing = await this.prisma.employees.findUnique({
|
|
where: { id },
|
|
include: { user: true, archive: true },
|
|
});
|
|
if (existing) {
|
|
//verify last_work_day is not null => trigger archivation
|
|
if(dto.last_work_day != undefined && existing.last_work_day == null) {
|
|
return this.archiveOnTermination(existing, dto);
|
|
}
|
|
//if null => regular update
|
|
return this.prisma.employees.update({
|
|
where: { id },
|
|
data: dto,
|
|
});
|
|
}
|
|
//if not found => fetch archives side for restoration
|
|
const archived = await this.prisma.employeesArchive.findFirst({
|
|
where: { employee_id: id },
|
|
include: { employee: true, user: true },
|
|
});
|
|
if (archived) {
|
|
//conditions for restoration
|
|
const restore = dto.last_work_day === null || dto.first_work_day != null;
|
|
if(restore) {
|
|
return this.restoreEmployee(archived, dto);
|
|
}
|
|
}
|
|
//if neither activated nor archivated => 404
|
|
return null;
|
|
}
|
|
|
|
//transfers the employee to archive and then delete from employees table
|
|
private async archiveOnTermination(existing: any, dto: UpdateEmployeeDto): Promise<any> {
|
|
return this.prisma.$transaction(async transaction => {
|
|
//archive insertion
|
|
const archived = await transaction.employeesArchive.create({
|
|
data: {
|
|
employee_id: existing.id,
|
|
user_id: existing.user_id,
|
|
first_name: existing.first_name,
|
|
last_name: existing.last_name,
|
|
external_payroll_id: existing.external_payroll_id,
|
|
company_code: existing.company_code,
|
|
first_Work_Day: existing.first_Work_Day,
|
|
last_work_day: existing.last_work_day,
|
|
supervisor_id: existing.supervisor_id ?? null,
|
|
},
|
|
});
|
|
//delete from employees table
|
|
await transaction.employees.delete({ where: { id: existing.id } });
|
|
//return archived employee
|
|
return archived
|
|
});
|
|
}
|
|
|
|
//transfers the employee from archive to the employees table
|
|
private async restoreEmployee(archived: any, dto: UpdateEmployeeDto): Promise<any> {
|
|
return this.prisma.$transaction(async transaction => {
|
|
//restores the archived employee into the employees table
|
|
const restored = await transaction.employees.create({
|
|
data: {
|
|
id: archived.employee_id,
|
|
user_id: archived.user_id,
|
|
external_payroll_id: dto.external_payroll_id ?? archived.external_payroll_id,
|
|
company_code: dto.company_code ?? archived.company_code,
|
|
first_work_day: dto.first_work_day ?? archived.first_Work_Day,
|
|
last_work_day: null,
|
|
supervisor_id: dto.supervisor_id ?? archived.supervisor_id,
|
|
},
|
|
});
|
|
//deleting archived entry by id
|
|
await transaction.employeesArchive.delete({ where: { id: archived.id } });
|
|
|
|
//return restored employee
|
|
return restored;
|
|
});
|
|
}
|
|
}
|