refactor(shifts): added date to overlap comparisons
This commit is contained in:
parent
0a3d4e2960
commit
eda1f86235
|
|
@ -5,13 +5,11 @@ import { ShiftsUpsertService } from "src/time-and-attendance/time-tracker/shifts
|
|||
import { CreateShiftResult, UpdateShiftResult } from "src/time-and-attendance/utils/type.utils";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { BankCodesResolver } from "src/time-and-attendance/utils/resolve-bank-type-id.utils";
|
||||
|
||||
@Controller('shift')
|
||||
export class ShiftController {
|
||||
constructor(
|
||||
private readonly upsert_service: ShiftsUpsertService,
|
||||
private readonly typeResolver: BankCodesResolver,
|
||||
){}
|
||||
|
||||
@Post('create')
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ export class ShiftsUpsertService {
|
|||
return {
|
||||
index: index,
|
||||
start: item.normed.start_time,
|
||||
end: item.normed.end_time
|
||||
end: item.normed.end_time,
|
||||
date: item.normed.date,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.start.getTime() - b.start.getTime());
|
||||
|
|
@ -101,8 +102,8 @@ export class ShiftsUpsertService {
|
|||
for (let j = 1; j < ordered.length; j++) {
|
||||
if (
|
||||
overlaps(
|
||||
{ start: ordered[j - 1].start, end: ordered[j - 1].end },
|
||||
{ start: ordered[j].start, end: ordered[j].end }
|
||||
{ start: ordered[j - 1].start, end: ordered[j - 1].end, date: ordered[j - 1].date },
|
||||
{ start: ordered[j].start, end: ordered[j].end, date: ordered[j].date },
|
||||
)
|
||||
) {
|
||||
const error = new ConflictException({
|
||||
|
|
@ -130,17 +131,17 @@ export class ShiftsUpsertService {
|
|||
{ length: dtos.length },
|
||||
() => ({ ok: false, error: new Error('uninitialized') }));
|
||||
|
||||
const existing_map = new Map<string, { start_time: Date; end_time: Date }[]>();
|
||||
const existing_map = new Map<string, { start_time: Date; end_time: Date, date: Date }[]>();
|
||||
|
||||
for (const { timesheet_id, day, key } of timesheet_keys) {
|
||||
const day_date = new Date(day);
|
||||
const rows = await tx.shifts.findMany({
|
||||
where: { timesheet_id, date: day_date },
|
||||
select: { start_time: true, end_time: true, id: true },
|
||||
select: { start_time: true, end_time: true, id: true, date: true },
|
||||
});
|
||||
existing_map.set(
|
||||
key,
|
||||
rows.map((row) => ({ start_time: row.start_time, end_time: row.end_time })),
|
||||
rows.map((row) => ({ start_time: row.start_time, end_time: row.end_time, date: row.date })),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +158,12 @@ export class ShiftsUpsertService {
|
|||
existing = [];
|
||||
existing_map.set(map_key, existing);
|
||||
}
|
||||
const hit = existing.find(e => overlaps({ start: e.start_time, end: e.end_time }, { start: normed.start_time, end: normed.end_time }));
|
||||
const hit = existing.find(exist => overlaps({
|
||||
start: exist.start_time, end: exist.end_time, date: exist.date
|
||||
}, {
|
||||
start: normed.start_time, end: normed.end_time, date:normed.date
|
||||
})
|
||||
);
|
||||
if (hit) {
|
||||
results[index] = {
|
||||
ok: false,
|
||||
|
|
@ -167,7 +173,7 @@ export class ShiftsUpsertService {
|
|||
conflicts: [{
|
||||
start_time: toStringFromHHmm(hit.start_time),
|
||||
end_time: toStringFromHHmm(hit.end_time),
|
||||
type: 'UNKNOWN',
|
||||
date: toStringFromDate(hit.date),
|
||||
}],
|
||||
}),
|
||||
};
|
||||
|
|
@ -192,13 +198,15 @@ export class ShiftsUpsertService {
|
|||
for (const { key } of timesheet_keys) {
|
||||
existing.push({
|
||||
start_time: normalizeHHmm(row.start_time),
|
||||
end_time: normalizeHHmm(row.end_time)
|
||||
end_time: normalizeHHmm(row.end_time),
|
||||
date: toDateFromString(row.date),
|
||||
});
|
||||
existing_map.set(
|
||||
key,
|
||||
existing.map(row => ({
|
||||
start_time: normalizeHHmm(row.start_time),
|
||||
end_time: normalizeHHmm(row.end_time),
|
||||
date: toDateFromString(row.date),
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
|
@ -291,7 +299,7 @@ export class ShiftsUpsertService {
|
|||
return { update, exist_shift, normed };
|
||||
});
|
||||
|
||||
const groups = new Map<string, { existing: { start: Date; end: Date; id: number }[], incoming: typeof planned_updates }>();
|
||||
const groups = new Map<string, { existing: { start: Date; end: Date; id: number; date: Date; }[], incoming: typeof planned_updates }>();
|
||||
function key(timesheet: number, d: Date) {
|
||||
const day_date = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
||||
return `${timesheet}|${day_date.getTime()}`;
|
||||
|
|
@ -307,9 +315,14 @@ export class ShiftsUpsertService {
|
|||
const day_date = new Date(group.date.getUTCFullYear(), group.date.getUTCMonth(), group.date.getUTCDate());
|
||||
const existing = await tx.shifts.findMany({
|
||||
where: { timesheet_id: group.timesheet_id, date: day_date },
|
||||
select: { id: true, start_time: true, end_time: true },
|
||||
select: { id: true, start_time: true, end_time: true, date: true },
|
||||
});
|
||||
groups.set(key(group.timesheet_id, day_date), { existing: existing.map(row => ({ id: row.id, start: row.start_time, end: row.end_time })), incoming: planned_updates });
|
||||
groups.set(key(group.timesheet_id, day_date), { existing: existing.map(row => ({
|
||||
id: row.id,
|
||||
start: row.start_time,
|
||||
end: row.end_time,
|
||||
date: row.date,
|
||||
})), incoming: planned_updates });
|
||||
}
|
||||
|
||||
for (const planned of planned_updates) {
|
||||
|
|
@ -317,7 +330,7 @@ export class ShiftsUpsertService {
|
|||
const group = groups.get(keys)!;
|
||||
|
||||
const conflict = group.existing.find(row =>
|
||||
row.id !== planned.exist_shift.id && overlaps({ start: row.start, end: row.end }, { start: planned.normed.start_time, end: planned.normed.end_time })
|
||||
row.id !== planned.exist_shift.id && overlaps({ start: row.start, end: row.end, date: row.date }, { start: planned.normed.start_time, end: planned.normed.end_time })
|
||||
);
|
||||
if (conflict) {
|
||||
return updates.map(exist =>
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ export function listPayYear(pay_year: number, anchorISO = ANCHOR_ISO) {
|
|||
return Array.from({ length: PERIODS_PER_YEAR }, (_, i) => computePeriod(pay_year, i + 1, anchorISO));
|
||||
}
|
||||
|
||||
export const overlaps = (a: { start: Date; end: Date }, b: { start: Date; end: Date }) =>
|
||||
!(a.end <= b.start || a.start >= b.end);
|
||||
export const overlaps = (a: { start: Date; end: Date, date?: Date; }, b: { start: Date; end: Date; date?: Date; }) =>
|
||||
((a.date === b.date) && !(a.end <= b.start || a.start >= b.end));
|
||||
|
||||
|
||||
export const hhmmFromLocal = (d: Date) =>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user