Create feeder circuits while linking boards

This commit is contained in:
Julian Appel 2026-09-28 22:14:30 +02:00
parent 552362bad1
commit ade21fe386
11 changed files with 960 additions and 40 deletions

View file

@ -366,20 +366,22 @@ export function createDistributionBoard(
);
}
export type UpdateDistributionBoardInput = {
floorId: string | null;
supplyType: NonNullable<DistributionBoardDto["supplyType"]>;
simultaneityFactor: number;
} & Partial<DistributionBoardInfoDto> &
Partial<
Pick<
DistributionBoardDto,
"feedingDistributionBoardId" | "feedingCircuitId"
>
>;
export function updateDistributionBoard(
projectId: string,
distributionBoardId: string,
input: {
floorId: string | null;
supplyType: NonNullable<DistributionBoardDto["supplyType"]>;
simultaneityFactor: number;
} & Partial<DistributionBoardInfoDto> &
Partial<
Pick<
DistributionBoardDto,
"feedingDistributionBoardId" | "feedingCircuitId"
>
>,
input: UpdateDistributionBoardInput,
expectedRevision: number
) {
return request<DistributionBoardCommandResultDto>(
@ -391,6 +393,41 @@ export function updateDistributionBoard(
);
}
export function createFeederCircuitAndUpdateDistributionBoard(
projectId: string,
distributionBoardId: string,
input: UpdateDistributionBoardInput & {
feedingDistributionBoardId: string;
feedingCircuitId: string;
},
circuit: CircuitSnapshot,
expectedRevision: number
) {
return executeProjectCommand(
projectId,
expectedRevision,
{
schemaVersion: 1,
type: "distribution-board.create-feeder-circuit",
payload: {
circuit,
boardUpdate: {
schemaVersion: 2,
type: "distribution-board.update",
payload: {
distributionBoardId,
changes: Object.entries(input).map(([field, value]) => ({
field,
value,
})),
},
},
},
},
"Einspeiseabgang anlegen und Verteilung verknüpfen"
);
}
export const documentLogoUrl = "/api/document-branding/logo";
export function getDocumentBranding() {

View file

@ -0,0 +1,68 @@
import type { CircuitSnapshot } from "../../domain/models/circuit-structure-project-command.model.js";
import type {
CircuitTreeResponseDto,
CircuitTreeSectionDto,
} from "../types";
import { buildCircuitInsertSnapshot } from "./circuit-structure-command";
export function getDefaultFeederCircuitSection(
tree: CircuitTreeResponseDto | undefined
) {
if (!tree) return undefined;
return (
tree.sections.find((section) => section.category === "three_phase") ??
tree.sections.find((section) => section.category !== undefined)
);
}
export function getNextFeederCircuitIdentifier(
section: CircuitTreeSectionDto
) {
let highestSuffix = 0;
for (const circuit of section.circuits) {
if (!circuit.equipmentIdentifier.startsWith(section.prefix)) continue;
const suffix = circuit.equipmentIdentifier.slice(section.prefix.length);
if (!/^\d+$/.test(suffix)) continue;
highestSuffix = Math.max(highestSuffix, Number(suffix));
}
return `${section.prefix}${highestSuffix + 1}`;
}
export function buildFeederCircuitSnapshot(input: {
id: string;
tree: CircuitTreeResponseDto;
sectionId: string;
displayName: string;
}): CircuitSnapshot {
const section = input.tree.sections.find(
(candidate) => candidate.id === input.sectionId
);
if (!section || !section.category) {
throw new Error("Die gewählte Stromkreisgruppe ist nicht verfügbar.");
}
const snapshot = buildCircuitInsertSnapshot({
id: input.id,
circuitListId: input.tree.circuitListId,
category: section.category,
deviceRows: [],
values: {
sectionId: section.id,
equipmentIdentifier: getNextFeederCircuitIdentifier(section),
displayName: input.displayName.trim() || undefined,
sortOrder:
section.circuits.length === 0
? 10
: Math.max(...section.circuits.map((circuit) => circuit.sortOrder)) +
10,
voltage:
section.category === "three_phase"
? input.tree.threePhaseVoltageV
: input.tree.singlePhaseVoltageV,
isReserve: true,
},
});
// A distribution-board feeder is not a generic final circuit. Its protection
// must be selected from the calculated load and cable, so no 16 A group
// default is persisted here.
return { ...snapshot, protectionDevice: null };
}

View file

@ -32,6 +32,10 @@ const commandTypeLabels: Record<string, string> = {
"project.update-settings": "Projekteinstellungen bearbeitet",
"distribution-board.insert": "Verteilung angelegt",
"distribution-board.update": "Verteilung bearbeitet",
"distribution-board.create-feeder-circuit":
"Einspeiseabgang angelegt und verknüpft",
"distribution-board.remove-feeder-circuit":
"Einspeiseabgang und Verknüpfung entfernt",
"distribution-board.delete": "Verteilung entfernt",
"distribution-board.insert-subtree": "Verteilung vollständig eingefügt",
"distribution-board.delete-subtree": "Verteilung vollständig entfernt",