refactor(shifts): changed to conflictException build for error management for the create function
This commit is contained in:
parent
eda1f86235
commit
95f369fcbc
|
|
@ -39,12 +39,15 @@ export class ShiftsUpsertService {
|
||||||
try {
|
try {
|
||||||
const normed = await this.normalizeShiftDto(dto);
|
const normed = await this.normalizeShiftDto(dto);
|
||||||
if (normed.end_time <= normed.start_time) {
|
if (normed.end_time <= normed.start_time) {
|
||||||
return {
|
const error = new ConflictException({
|
||||||
index,
|
error_code: 'SHIFT_OVERLAP',
|
||||||
error: new BadRequestException(
|
conflicts: [{
|
||||||
`end_time must be greater than start_time (index ${index})`
|
start_time: toStringFromHHmm(normed.start_time),
|
||||||
),
|
end_time: toStringFromHHmm(normed.end_time),
|
||||||
};
|
date: toStringFromDate(normed.date),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
return { index, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
const timesheet = await this.prisma.timesheets.findUnique({
|
const timesheet = await this.prisma.timesheets.findUnique({
|
||||||
|
|
@ -52,7 +55,15 @@ export class ShiftsUpsertService {
|
||||||
select: timesheet_select,
|
select: timesheet_select,
|
||||||
});
|
});
|
||||||
if (!timesheet) {
|
if (!timesheet) {
|
||||||
return { index, error: new NotFoundException(`Timesheet not found`) };
|
const error = new ConflictException({
|
||||||
|
error_code: 'INVALID_TIMESHEET',
|
||||||
|
conflicts: [{
|
||||||
|
start_time: toStringFromHHmm(normed.start_time),
|
||||||
|
end_time: toStringFromHHmm(normed.end_time),
|
||||||
|
date: toStringFromDate(normed.date),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
return { index, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -107,21 +118,17 @@ export class ShiftsUpsertService {
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const error = new ConflictException({
|
const error = new ConflictException({
|
||||||
error_code: 'SHIFT_OVERLAP_BATCH',
|
error_code: 'SHIFT_OVERLAP',
|
||||||
message: 'New shift overlaps with another shift in the same batch (same day).',
|
conflicts: [{
|
||||||
|
start_time: toStringFromHHmm(ordered[j].start),
|
||||||
|
end_time: toStringFromHHmm(ordered[j].end),
|
||||||
|
date: toStringFromDate(ordered[j].date),
|
||||||
|
}],
|
||||||
});
|
});
|
||||||
return dtos.map((_dto, key) =>
|
return dtos.map((_dto, key) =>
|
||||||
indices.includes(key)
|
indices.includes(key)
|
||||||
? ({
|
? ({ ok: false, error } as CreateShiftResult)
|
||||||
ok: false,
|
: ({ ok: false, error }),
|
||||||
error
|
|
||||||
} as CreateShiftResult)
|
|
||||||
: ({
|
|
||||||
ok: false,
|
|
||||||
error: new BadRequestException(
|
|
||||||
'Batch aborted due to overlaps in another date group'
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -139,10 +146,7 @@ export class ShiftsUpsertService {
|
||||||
where: { timesheet_id, date: day_date },
|
where: { timesheet_id, date: day_date },
|
||||||
select: { start_time: true, end_time: true, id: true, date: true },
|
select: { start_time: true, end_time: true, id: true, date: true },
|
||||||
});
|
});
|
||||||
existing_map.set(
|
existing_map.set( key, rows.map((row) => ({ start_time: row.start_time, end_time: row.end_time, date: row.date })));
|
||||||
key,
|
|
||||||
rows.map((row) => ({ start_time: row.start_time, end_time: row.end_time, date: row.date })),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
normed_shifts.forEach((x, i) => {
|
normed_shifts.forEach((x, i) => {
|
||||||
|
|
@ -158,18 +162,13 @@ export class ShiftsUpsertService {
|
||||||
existing = [];
|
existing = [];
|
||||||
existing_map.set(map_key, existing);
|
existing_map.set(map_key, existing);
|
||||||
}
|
}
|
||||||
const hit = existing.find(exist => overlaps({
|
const hit = existing.find(exist => overlaps({ start: exist.start_time, end: exist.end_time, date: exist.date },
|
||||||
start: exist.start_time, end: exist.end_time, date: exist.date
|
{ start: normed.start_time, end: normed.end_time, date:normed.date}));
|
||||||
}, {
|
|
||||||
start: normed.start_time, end: normed.end_time, date:normed.date
|
|
||||||
})
|
|
||||||
);
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
results[index] = {
|
results[index] = {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: new ConflictException({
|
error: new ConflictException({
|
||||||
error_code: 'SHIFT_OVERLAP',
|
error_code: 'SHIFT_OVERLAP',
|
||||||
message: 'New shift overlaps with existing shift(s)',
|
|
||||||
conflicts: [{
|
conflicts: [{
|
||||||
start_time: toStringFromHHmm(hit.start_time),
|
start_time: toStringFromHHmm(hit.start_time),
|
||||||
end_time: toStringFromHHmm(hit.end_time),
|
end_time: toStringFromHHmm(hit.end_time),
|
||||||
|
|
@ -248,9 +247,7 @@ export class ShiftsUpsertService {
|
||||||
|
|
||||||
const updates: UpdateShiftPayload[] = await Promise.all(dtos.map((item) => {
|
const updates: UpdateShiftPayload[] = await Promise.all(dtos.map((item) => {
|
||||||
const { id, ...rest } = item;
|
const { id, ...rest } = item;
|
||||||
if (!Number.isInteger(id)) {
|
if (!Number.isInteger(id)) throw new ConflictException({ error_code: 'INVALID_SHIFT'});
|
||||||
throw new BadRequestException('Update shift payload is missing a valid id');
|
|
||||||
}
|
|
||||||
|
|
||||||
const changes: UpdateShiftChanges = {};
|
const changes: UpdateShiftChanges = {};
|
||||||
if (rest.date !== undefined) changes.date = rest.date;
|
if (rest.date !== undefined) changes.date = rest.date;
|
||||||
|
|
@ -338,8 +335,11 @@ export class ShiftsUpsertService {
|
||||||
? ({
|
? ({
|
||||||
ok: false, id: exist.id, error: new ConflictException({
|
ok: false, id: exist.id, error: new ConflictException({
|
||||||
error_code: 'SHIFT_OVERLAP',
|
error_code: 'SHIFT_OVERLAP',
|
||||||
message: 'New shift overlaps with existing shift(s)',
|
conflicts: [{
|
||||||
conflicts: [{ start_time: toStringFromHHmm(conflict.start), end_time: toStringFromHHmm(conflict.end), type: 'UNKNOWN' }],
|
start_time: toStringFromHHmm(conflict.start),
|
||||||
|
end_time: toStringFromHHmm(conflict.end),
|
||||||
|
date: toStringFromDate(conflict.date),
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
} as UpdateShiftResult)
|
} as UpdateShiftResult)
|
||||||
: ({ ok: false, id: exist.id, error: new BadRequestException('Batch aborted due to overlap in another update') })
|
: ({ ok: false, id: exist.id, error: new BadRequestException('Batch aborted due to overlap in another update') })
|
||||||
|
|
@ -347,17 +347,34 @@ export class ShiftsUpsertService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const regoup_by_day = new Map<string, { id: number; start: Date; end: Date }[]>();
|
const regoup_by_day = new Map<string, { id: number; start: Date; end: Date; date: Date }[]>();
|
||||||
for (const planned of planned_updates) {
|
for (const planned of planned_updates) {
|
||||||
const keys = key(planned.exist_shift.timesheet_id, planned.normed.date);
|
const keys = key(planned.exist_shift.timesheet_id, planned.normed.date);
|
||||||
if (!regoup_by_day.has(keys)) regoup_by_day.set(keys, []);
|
if (!regoup_by_day.has(keys)) regoup_by_day.set(keys, []);
|
||||||
regoup_by_day.get(keys)!.push({ id: planned.exist_shift.id, start: planned.normed.start_time, end: planned.normed.end_time });
|
regoup_by_day.get(keys)!.push({
|
||||||
|
id: planned.exist_shift.id,
|
||||||
|
start: planned.normed.start_time,
|
||||||
|
end: planned.normed.end_time,
|
||||||
|
date: planned.normed.date
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const arr of regoup_by_day.values()) {
|
for (const arr of regoup_by_day.values()) {
|
||||||
arr.sort((a, b) => a.start.getTime() - b.start.getTime());
|
arr.sort((a, b) => a.start.getTime() - b.start.getTime());
|
||||||
for (let i = 1; i < arr.length; i++) {
|
for (let i = 1; i < arr.length; i++) {
|
||||||
if (overlaps({ start: arr[i - 1].start, end: arr[i - 1].end }, { start: arr[i].start, end: arr[i].end })) {
|
if (overlaps(
|
||||||
const error = new ConflictException({ error_code: 'SHIFT_OVERLAP_BATCH', message: 'Overlaps between updates within the same day.' });
|
{ start: arr[i - 1].start, end: arr[i - 1].end, date: arr[i - 1].date },
|
||||||
|
{ start: arr[i].start, end: arr[i].end, date: arr[i].date })
|
||||||
|
) {
|
||||||
|
const error = new ConflictException({
|
||||||
|
error_code: 'SHIFT_OVERLAP',
|
||||||
|
conflicts: [{
|
||||||
|
start_time: toStringFromHHmm(arr[i].start),
|
||||||
|
end_time: toStringFromHHmm(arr[i].end),
|
||||||
|
date: toStringFromDate(arr[i].date),
|
||||||
|
}],
|
||||||
|
|
||||||
|
});
|
||||||
return updates.map(exist => ({ ok: false, id: exist.id, error: error }));
|
return updates.map(exist => ({ ok: false, id: exist.id, error: error }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user