import type { Prisma } from "@capakraken/db"; import { CreateRateCardLineSchema, CreateRateCardSchema, UpdateRateCardLineSchema, UpdateRateCardSchema, } from "@capakraken/shared"; import { z } from "zod"; type RateCardListInput = { isActive?: boolean | undefined; search?: string | undefined; clientId?: string | undefined; effectiveAt?: Date | undefined; }; type CreateRateCardInput = z.infer; type CreateRateCardLineInput = z.infer; type UpdateRateCardInput = z.infer; type UpdateRateCardLineInput = z.infer; export const rateCardSummaryInclude = { _count: { select: { lines: true } }, client: { select: { id: true, name: true, code: true } }, } as const; export const rateCardLineOrderBy: Prisma.RateCardLineOrderByWithRelationInput[] = [ { chapter: "asc" }, { seniority: "asc" }, { createdAt: "asc" }, ]; export const rateCardDetailInclude = { client: { select: { id: true, name: true, code: true } }, lines: { select: { id: true, rateCardId: true, roleId: true, chapter: true, seniority: true, location: true, workType: true, serviceGroup: true, costRateCents: true, billRateCents: true, machineRateCents: true, attributes: true, role: { select: { id: true, name: true } }, }, orderBy: rateCardLineOrderBy, }, } as const; export const rateCardCreateInclude = { lines: { select: rateCardDetailInclude.lines.select, }, } as const; function buildRateCardLineCoreData( line: CreateRateCardLineInput, ) { return { ...(line.roleId !== undefined ? { roleId: line.roleId } : {}), ...(line.chapter !== undefined ? { chapter: line.chapter } : {}), ...(line.location !== undefined ? { location: line.location } : {}), ...(line.seniority !== undefined ? { seniority: line.seniority } : {}), ...(line.workType !== undefined ? { workType: line.workType } : {}), ...(line.serviceGroup !== undefined ? { serviceGroup: line.serviceGroup } : {}), costRateCents: line.costRateCents, ...(line.billRateCents !== undefined ? { billRateCents: line.billRateCents } : {}), ...(line.machineRateCents !== undefined ? { machineRateCents: line.machineRateCents } : {}), attributes: line.attributes as Prisma.InputJsonValue, }; } export function buildRateCardListWhere( input?: RateCardListInput, ): Prisma.RateCardWhereInput { return { ...(input?.isActive !== undefined ? { isActive: input.isActive } : {}), ...(input?.clientId !== undefined ? { clientId: input.clientId } : {}), ...(input?.search ? { name: { contains: input.search, mode: "insensitive" } } : {}), ...(input?.effectiveAt ? { OR: [ { effectiveFrom: null }, { effectiveFrom: { lte: input.effectiveAt } }, ], AND: [ { OR: [ { effectiveTo: null }, { effectiveTo: { gte: input.effectiveAt } }, ], }, ], } : {}), }; } export function buildRateCardCreateData( input: CreateRateCardInput, ): Prisma.RateCardUncheckedCreateInput { const { lines, ...cardData } = input; return { name: cardData.name, currency: cardData.currency, ...(cardData.effectiveFrom !== undefined ? { effectiveFrom: cardData.effectiveFrom } : {}), ...(cardData.effectiveTo !== undefined ? { effectiveTo: cardData.effectiveTo } : {}), ...(cardData.source !== undefined ? { source: cardData.source } : {}), ...(cardData.clientId !== undefined ? { clientId: cardData.clientId } : {}), lines: { create: lines.map((line) => buildRateCardNestedLineCreateData(line)), }, } as Prisma.RateCardUncheckedCreateInput; } export function buildRateCardUpdateData( input: UpdateRateCardInput, ): Prisma.RateCardUncheckedUpdateInput { return { ...(input.name !== undefined ? { name: input.name } : {}), ...(input.currency !== undefined ? { currency: input.currency } : {}), ...(input.effectiveFrom !== undefined ? { effectiveFrom: input.effectiveFrom } : {}), ...(input.effectiveTo !== undefined ? { effectiveTo: input.effectiveTo } : {}), ...(input.source !== undefined ? { source: input.source } : {}), ...(input.clientId !== undefined ? { clientId: input.clientId } : {}), ...(input.isActive !== undefined ? { isActive: input.isActive } : {}), }; } export function buildRateCardNestedLineCreateData( line: CreateRateCardLineInput, ): Prisma.RateCardLineUncheckedCreateWithoutRateCardInput { return buildRateCardLineCoreData(line) as Prisma.RateCardLineUncheckedCreateWithoutRateCardInput; } export function buildRateCardLineCreateData( rateCardId: string, line: CreateRateCardLineInput, ): Prisma.RateCardLineUncheckedCreateInput { return { rateCardId, ...buildRateCardLineCoreData(line), } as Prisma.RateCardLineUncheckedCreateInput; } export function buildRateCardLineUpdateData( input: UpdateRateCardLineInput, ): Prisma.RateCardLineUpdateInput { const updateData: Prisma.RateCardLineUpdateInput = {}; if (input.roleId !== undefined) { updateData.role = input.roleId ? { connect: { id: input.roleId } } : { disconnect: true }; } if (input.chapter !== undefined) updateData.chapter = input.chapter; if (input.location !== undefined) updateData.location = input.location; if (input.seniority !== undefined) updateData.seniority = input.seniority; if (input.workType !== undefined) updateData.workType = input.workType; if (input.serviceGroup !== undefined) updateData.serviceGroup = input.serviceGroup; if (input.costRateCents !== undefined) updateData.costRateCents = input.costRateCents; if (input.billRateCents !== undefined) updateData.billRateCents = input.billRateCents; if (input.machineRateCents !== undefined) updateData.machineRateCents = input.machineRateCents; if (input.attributes !== undefined) updateData.attributes = input.attributes as Prisma.InputJsonValue; return updateData; } export function buildRateCardCreateAuditAfter( input: Pick, ) { return { name: input.name, currency: input.currency, lineCount: input.lines.length, }; } export function buildRateCardLineCreateAuditAfter( input: { rateCardId: string; line: Pick; }, ) { return { rateCardId: input.rateCardId, costRateCents: input.line.costRateCents, billRateCents: input.line.billRateCents, chapter: input.line.chapter ?? null, }; } export function buildRateCardReplaceLinesAuditAfter( replacedLineCount: number, ) { return { replacedLineCount }; }