import { fmtDate, rangesOverlap, toDate } from "./timeline-read-shared.js"; export interface TimelineProjectAssignmentConflict { assignmentId: string; resourceId: string; resourceName: string | null; startDate: string | null; endDate: string | null; hoursPerDay: number; overlapCount: number; crossProjectOverlapCount: number; overlaps: Array<{ id: string; projectId: string | null; projectName: string | null; projectShortCode: string | null; startDate: string | null; endDate: string | null; hoursPerDay: number; status: string; sameProject: boolean; }>; } export function buildTimelineProjectAssignmentConflicts(input: { projectId: string; assignments: Array<{ id: string; resourceId: string | null; resource?: { displayName?: string | null } | null; startDate: Date | string; endDate: Date | string; hoursPerDay: number; }>; allResourceAllocations: Array<{ id: string; resourceId: string | null; projectId: string | null; project?: { name?: string | null; shortCode?: string | null } | null; startDate: Date | string; endDate: Date | string; hoursPerDay: number; status: string; }>; }): TimelineProjectAssignmentConflict[] { return input.assignments .filter((assignment) => assignment.resourceId && assignment.resource) .map((assignment) => { const overlaps = input.allResourceAllocations .filter((booking) => ( booking.resourceId === assignment.resourceId && booking.id !== assignment.id && rangesOverlap( toDate(booking.startDate), toDate(booking.endDate), toDate(assignment.startDate), toDate(assignment.endDate), ) )) .map((booking) => ({ id: booking.id, projectId: booking.projectId, projectName: booking.project?.name ?? null, projectShortCode: booking.project?.shortCode ?? null, startDate: fmtDate(toDate(booking.startDate)), endDate: fmtDate(toDate(booking.endDate)), hoursPerDay: booking.hoursPerDay, status: booking.status, sameProject: booking.projectId === input.projectId, })); return { assignmentId: assignment.id, resourceId: assignment.resourceId!, resourceName: assignment.resource?.displayName ?? null, startDate: fmtDate(toDate(assignment.startDate)), endDate: fmtDate(toDate(assignment.endDate)), hoursPerDay: assignment.hoursPerDay, overlapCount: overlaps.length, crossProjectOverlapCount: overlaps.filter((booking) => !booking.sameProject).length, overlaps, }; }); }