refactor(schedules_employees): refactor schema relations between employees and presets
This commit is contained in:
parent
3e0e835cd8
commit
d913f59eb5
|
|
@ -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;
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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` };
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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 { }
|
||||
|
|
@ -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<Result<boolean, string>> {
|
||||
async createPreset(dto: SchedulePresetsDto): Promise<Result<boolean, string>> {
|
||||
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: {
|
||||
|
|
|
|||
|
|
@ -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<Result<boolean, string>> {
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Result<PresetResponse[], string>> {
|
||||
async getSchedulePresets(): Promise<Result<PresetResponse[], string>> {
|
||||
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: {
|
||||
|
|
|
|||
|
|
@ -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<Result<boolean, string>> {
|
||||
|
||||
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<Result<boolean, string>> {
|
||||
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<Result<boolean, string>> {
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ export class ShiftsCreateService {
|
|||
//_________________________________________________________________
|
||||
// CREATE WRAPPER FUNCTION FOR ONE OR MANY INPUT
|
||||
//_________________________________________________________________
|
||||
async createOneOrManyShifts(email: string, shifts: ShiftDto[]): Promise<Result<ShiftDto[], string>> {
|
||||
async createOneOrManyShifts(email: string, shifts: ShiftDto[]): Promise<Result<boolean, string>> {
|
||||
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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export class ShiftsUpdateDeleteService {
|
|||
private readonly timesheetResolver: EmployeeTimesheetResolver,
|
||||
) { }
|
||||
|
||||
async updateOneOrManyShifts(shifts: ShiftDto[], email: string): Promise<Result<ShiftDto[], string>> {
|
||||
async updateOneOrManyShifts(shifts: ShiftDto[], email: string): Promise<Result<boolean, string>> {
|
||||
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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -34,11 +44,12 @@ import { ShiftsUpdateDeleteService } from "src/time-and-attendance/shifts/servic
|
|||
ExpensesModule,
|
||||
PayperiodsModule,
|
||||
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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user