fix(shifts): fix overlap checks for updating shifts
This commit is contained in:
parent
2003b5357d
commit
0764eebc98
|
|
@ -22,8 +22,9 @@ export class ShiftController {
|
|||
}
|
||||
|
||||
@Patch('update')
|
||||
updateBatch( @Body() dtos: ShiftDto[]): Promise<Result<ShiftDto[], string>>{
|
||||
return this.update_delete_service.updateOneOrManyShifts(dtos);
|
||||
updateBatch( @Body() dtos: ShiftDto[], @Req() req): Promise<Result<ShiftDto[], string>>{
|
||||
const email = req.user?.email;
|
||||
return this.update_delete_service.updateOneOrManyShifts(dtos, email);
|
||||
}
|
||||
|
||||
@Delete(':shift_id')
|
||||
|
|
|
|||
|
|
@ -6,21 +6,27 @@ import { Injectable } from "@nestjs/common";
|
|||
import { Normalized } from "src/time-and-attendance/utils/type.utils";
|
||||
import { ShiftDto } from "src/time-and-attendance/time-tracker/shifts/dtos/shift-create.dto";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { EmployeeTimesheetResolver } from "src/time-and-attendance/utils/resolve-timesheet.utils";
|
||||
|
||||
@Injectable()
|
||||
export class ShiftsUpdateDeleteService {
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly typeResolver: BankCodesResolver,
|
||||
private readonly timesheetResolver: EmployeeTimesheetResolver,
|
||||
) { }
|
||||
|
||||
async updateOneOrManyShifts(shifts: ShiftDto[]): Promise<Result<ShiftDto[], string>> {
|
||||
async updateOneOrManyShifts(shifts: ShiftDto[], email: string): Promise<Result<ShiftDto[], string>> {
|
||||
try {
|
||||
//verify if array is empty or not
|
||||
if (!Array.isArray(shifts) || shifts.length === 0) return { success: false, error: 'No data received' };
|
||||
|
||||
//check for overlap inside dto objects
|
||||
const overlap_check = await this.overlapChecker(shifts);
|
||||
if (!overlap_check.success) return overlap_check;
|
||||
|
||||
//calls the update functions and await the return of successfull result or not
|
||||
const results = await Promise.allSettled(shifts.map(shift => this.updateShift(shift)));
|
||||
const results = await Promise.allSettled(shifts.map(shift => this.updateShift(shift, email)));
|
||||
|
||||
//return arrays of updated shifts or errors
|
||||
const updated_shifts: ShiftDto[] = [];
|
||||
|
|
@ -50,11 +56,14 @@ export class ShiftsUpdateDeleteService {
|
|||
//_________________________________________________________________
|
||||
// UPDATE
|
||||
//_________________________________________________________________
|
||||
async updateShift(dto: ShiftDto): Promise<Result<ShiftDto, string>> {
|
||||
async updateShift(dto: ShiftDto, email): Promise<Result<ShiftDto, string>> {
|
||||
try {
|
||||
const timesheet = await this.timesheetResolver.findTimesheetIdByEmail(email, toDateFromString(dto.date));
|
||||
if (!timesheet.success) return { success: false, error: ' timesheet not found' }
|
||||
|
||||
//finds original shift
|
||||
const original = await this.prisma.shifts.findFirst({
|
||||
where: { id: dto.id },
|
||||
where: { id: dto.id, timesheet_id: timesheet.data.id },
|
||||
select: shift_select,
|
||||
});
|
||||
if (!original) return { success: false, error: `Shift with id: ${dto.id} not found` };
|
||||
|
|
@ -69,12 +78,10 @@ export class ShiftsUpdateDeleteService {
|
|||
+ `end_time: ${toStringFromHHmm(normed_shift.data.end_time)},`
|
||||
+ `date: ${toStringFromDate(normed_shift.data.date)}.`
|
||||
};
|
||||
const overlap_check = await this.overlapChecker(normed_shift.data);
|
||||
if(!overlap_check.success) return { success: false, error: 'Invalid shift, overlaps with existing shifts'}
|
||||
|
||||
//finds bank_code_id using the type
|
||||
const bank_code = await this.typeResolver.findBankCodeIDByType(dto.type);
|
||||
if (!bank_code.success) return { success: false, error: 'No bank_code_id found' };
|
||||
if (!bank_code.success) return { success: false, error: bank_code.error };
|
||||
|
||||
//updates sent to DB
|
||||
const updated = await this.prisma.shifts.update({
|
||||
|
|
@ -147,28 +154,23 @@ export class ShiftsUpdateDeleteService {
|
|||
return { success: true, data: { date, start_time, end_time, bank_code_id: bank_code_id.data } };
|
||||
}
|
||||
|
||||
private overlapChecker = async (dto: Normalized): Promise<Result<void, string>> => {
|
||||
|
||||
const existing_shifts = await this.prisma.shifts.findMany({
|
||||
where: { date: dto.date },
|
||||
select: { id: true, date: true, start_time: true, end_time: true },
|
||||
});
|
||||
for (const existing of existing_shifts) {
|
||||
const existing_start = toDateFromString(existing.start_time);
|
||||
const existing_end = toDateFromString(existing.end_time);
|
||||
const existing_date = toDateFromString(existing.date);
|
||||
|
||||
private overlapChecker = async (shifts: ShiftDto[]): Promise<Result<void, string>> => {
|
||||
for (const shift_a of shifts) {
|
||||
for(const shift_b of shifts){
|
||||
if(shift_a.date === shift_b.date){
|
||||
const has_overlap = overlaps(
|
||||
{ start: dto.start_time, end: dto.end_time, date: dto.date },
|
||||
{ start: existing_start, end: existing_end, date: existing_date },
|
||||
{ start: toHHmmFromString(shift_a.start_time), end: toHHmmFromString(shift_a.end_time) },
|
||||
{ start: toDateFromString(shift_b.start_time), end: toDateFromString(shift_b.end_time) },
|
||||
);
|
||||
if (has_overlap) {
|
||||
return {
|
||||
success: false,
|
||||
error: `SHIFT_OVERLAP`
|
||||
+ `new shift: ${toStringFromHHmm(dto.start_time)}–${toStringFromHHmm(dto.end_time)} `
|
||||
+ `existing shift: ${toStringFromHHmm(existing.start_time)}–${toStringFromHHmm(existing.end_time)} `
|
||||
+ `date: ${toStringFromDate(dto.date)})`,
|
||||
+ `new shift: ${shift_a.start_time}–${shift_a.end_time} `
|
||||
+ `existing shift: ${shift_b.start_time}–${shift_b.end_time} `
|
||||
+ `date: ${shift_a.date})`,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user