57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { FastifyInstance } from "fastify"
|
|
import { eq } from "drizzle-orm"
|
|
import { costcentres } from "../../db/schema"
|
|
|
|
export async function validateCostCentreParent(
|
|
server: FastifyInstance,
|
|
tenantId: number,
|
|
costCentreId: string | null,
|
|
parentCostcentreId: string | null
|
|
) {
|
|
if (!parentCostcentreId) {
|
|
return null
|
|
}
|
|
|
|
const hierarchyRows = await server.db
|
|
.select({
|
|
id: costcentres.id,
|
|
parentCostcentre: costcentres.parentCostcentre,
|
|
})
|
|
.from(costcentres)
|
|
.where(eq(costcentres.tenant, tenantId))
|
|
|
|
const hierarchyMap = new Map(
|
|
hierarchyRows.map((row) => [row.id, row.parentCostcentre || null])
|
|
)
|
|
|
|
if (!hierarchyMap.has(parentCostcentreId)) {
|
|
return "Die übergeordnete Kostenstelle wurde nicht gefunden."
|
|
}
|
|
|
|
if (costCentreId && parentCostcentreId === costCentreId) {
|
|
return "Eine Kostenstelle kann nicht sich selbst als übergeordnete Kostenstelle haben."
|
|
}
|
|
|
|
if (!costCentreId) {
|
|
return null
|
|
}
|
|
|
|
let currentParentId: string | null = parentCostcentreId
|
|
const visited = new Set<string>()
|
|
|
|
while (currentParentId) {
|
|
if (currentParentId === costCentreId) {
|
|
return "Die ausgewählte übergeordnete Kostenstelle würde einen Zyklus erzeugen."
|
|
}
|
|
|
|
if (visited.has(currentParentId)) {
|
|
break
|
|
}
|
|
|
|
visited.add(currentParentId)
|
|
currentParentId = hierarchyMap.get(currentParentId) || null
|
|
}
|
|
|
|
return null
|
|
}
|