import { Prisma } from "@capakraken/db"; import { PROJECT_PLANNING_DEMAND_INCLUDE, TIMELINE_ASSIGNMENT_INCLUDE, } from "./project-planning-read-model.js"; import type { TimelineEntriesDbClient, TimelineEntriesFilters } from "./timeline-read-shared.js"; export async function resolveTimelineEntryResourceIds( db: TimelineEntriesDbClient, input: Pick, ): Promise { if (input.resourceIds && input.resourceIds.length > 0) { return input.resourceIds; } const hasChapters = !!input.chapters?.length; const hasEids = !!input.eids?.length; const hasCountry = !!input.countryCodes?.length; if (!hasChapters && !hasEids && !hasCountry) { return undefined; } const andConditions: Record[] = []; if (hasChapters) { andConditions.push({ chapter: { in: input.chapters } }); } if (hasEids) { andConditions.push({ eid: { in: input.eids } }); } if (hasCountry) { andConditions.push({ country: { code: { in: input.countryCodes } } }); } const matching = await db.resource.findMany({ where: (andConditions.length === 1 ? andConditions[0]! : { AND: andConditions }) as Prisma.ResourceWhereInput, select: { id: true }, }); return matching.map((resource) => resource.id); } export async function resolveTimelineEntryProjectIds( db: TimelineEntriesDbClient, input: Pick, ): Promise { if (!input.clientIds?.length) { return input.projectIds; } const matchingProjects = await db.project.findMany({ where: { clientId: { in: input.clientIds } }, select: { id: true }, }); const clientProjectIds = matchingProjects.map((project) => project.id); if (!input.projectIds?.length) { return clientProjectIds; } const allowedIds = new Set(clientProjectIds); return input.projectIds.filter((projectId) => allowedIds.has(projectId)); } export async function loadTimelineEntryRecords( db: TimelineEntriesDbClient, input: TimelineEntriesFilters, ) { const effectiveResourceIds = await resolveTimelineEntryResourceIds(db, input); const effectiveProjectIds = await resolveTimelineEntryProjectIds(db, input); const excludeDemands = effectiveResourceIds !== undefined; const [demandRequirements, assignments] = await Promise.all([ excludeDemands ? Promise.resolve([]) : db.demandRequirement.findMany({ where: { status: { not: "CANCELLED" }, startDate: { lte: input.endDate }, endDate: { gte: input.startDate }, ...(effectiveProjectIds ? { projectId: { in: effectiveProjectIds } } : {}), }, include: PROJECT_PLANNING_DEMAND_INCLUDE, orderBy: [{ startDate: "asc" }, { projectId: "asc" }], }), db.assignment.findMany({ where: { status: { not: "CANCELLED" }, startDate: { lte: input.endDate }, endDate: { gte: input.startDate }, ...(effectiveResourceIds ? { resourceId: { in: effectiveResourceIds } } : {}), ...(effectiveProjectIds ? { projectId: { in: effectiveProjectIds } } : {}), }, include: TIMELINE_ASSIGNMENT_INCLUDE, orderBy: [{ startDate: "asc" }, { resourceId: "asc" }], }), ]); return { demandRequirements, assignments }; }