import { Injectable } from "@nestjs/common"; import { PrismaService } from "src/prisma/prisma.service"; import { SchedulePresetsDto } from "src/time-and-attendance/schedule-presets/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 SchedulePresetUpdateService { constructor( private readonly prisma: PrismaService, private readonly typeResolver: BankCodesResolver, ) { } //_________________________________________________________________ // UPDATE //_________________________________________________________________ async updatePreset(dto: SchedulePresetsDto): Promise> { const existing = await this.prisma.schedulePresets.findFirst({ where: { id: dto.id, name: dto.name }, select: { id: true, is_default: true, shifts: true, }, }); if (!existing) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` }; const normalized_shifts = dto.shifts.map((shift) => ({ ...shift, start: toDateFromHHmm(shift.start_time), end: toDateFromHHmm(shift.end_time), })); for (const preset_shifts of normalized_shifts) { for (const other_shifts of normalized_shifts) { if (preset_shifts === other_shifts) continue; if (preset_shifts.week_day !== other_shifts.week_day) continue; const has_overlap = overlaps( { start: preset_shifts.start, end: preset_shifts.end }, { start: other_shifts.start, end: other_shifts.end }, ) if (has_overlap) return { success: false, error: 'SCHEDULE_PRESET_OVERLAP' }; } } const bank_code_results = await Promise.all(dto.shifts.map((shift) => this.typeResolver.findBankCodeIDByType(shift.type), )); for (const result of bank_code_results) { if (!result.success) return { success: false, error: 'INVALID_SCHEDULE_PRESET' } } await this.prisma.$transaction(async (tx) => { if (dto.is_default) { await tx.schedulePresets.updateMany({ where: { is_default: true, NOT: { id: existing.id }, }, data: { is_default: false }, }); } await tx.schedulePresetShifts.deleteMany({ where: { preset_id: existing.id } }); await tx.schedulePresets.update({ where: { id: existing.id }, data: { name: dto.name, is_default: dto.is_default ?? false, shifts: { create: dto.shifts.map((shift, index) => { const result = bank_code_results[index] as { success: true, data: number }; return { week_day: shift.week_day, start_time: toDateFromHHmm(shift.start_time), end_time: toDateFromHHmm(shift.end_time), is_remote: shift.is_remote ?? false, bank_code: { connect: { id: result.data }, }, } }), }, }, }); }); return { success: true, data: true }; } }