import { type BlfEntry, parseBlfs, serializeBlfs, } from "./blf-xml"; import { type SlotContract, isManagedSlot, isReservedSlot, isSharedParkingSlot, managedSlotCount, } from "./slot-contract"; export interface Colleague { id: number; number: string; firstName: string; lastName: string; } export interface MergeResult { xml: string; changed: boolean; overflow: number; placed: number; } export function sortColleagues(colleagues: Colleague[]): Colleague[] { return [...colleagues].sort((a, b) => a.number.localeCompare(b.number, "en", { numeric: true })); } export function mergeDepartmentBlfs(input: { currentXml: string | undefined | null; selfExtension: string; colleagues: Colleague[]; contract: SlotContract; }): MergeResult { const current = parseBlfs(input.currentXml); const others = sortColleagues( input.colleagues.filter((c) => c.number !== input.selfExtension) ); const slotCount = managedSlotCount(input.contract); const placedColleagues = others.slice(0, slotCount); const overflow = Math.max(0, others.length - slotCount); const preserved = current.filter((entry) => { if (entry.blfNo === input.contract.ownLine) { return false; } if (isReservedSlot(input.contract, entry.blfNo)) { return false; } if (isSharedParkingSlot(input.contract, entry.blfNo)) { return false; } if (isManagedSlot(input.contract, entry.blfNo)) { return false; } return true; }); const existingOwnLine = current.find((entry) => entry.blfNo === input.contract.ownLine); const ownLine: BlfEntry = { id: existingOwnLine?.blfType === "Line" ? existingOwnLine.id : "-1", blfNo: input.contract.ownLine, blfType: "Line", blfTypeId: "6", value: "", }; const parking: BlfEntry[] = input.contract.sharedParking.map((slot) => { const existing = current.find( (entry) => entry.blfNo === slot.blfNo && entry.blfType === "SharedParking" && entry.value === slot.value ); return { id: existing?.id ?? "-1", blfNo: slot.blfNo, blfType: "SharedParking", blfTypeId: existing?.blfTypeId ?? "3", value: slot.value, }; }); const managed: BlfEntry[] = placedColleagues.map((colleague, index) => ({ id: String(colleague.id), blfNo: input.contract.managedStart + index, blfType: "BLF", blfTypeId: "0", value: colleague.number, })); const nextXml = serializeBlfs([...preserved, ownLine, ...parking, ...managed]); return { xml: nextXml, changed: serializeBlfs(current) !== nextXml, overflow, placed: placedColleagues.length, }; }