Renumber circuit groups explicitly
This commit is contained in:
@@ -10,6 +10,9 @@ import type { CircuitTreeSectionDto } from "../types";
|
||||
import type {
|
||||
CircuitGroupReorderAssignment,
|
||||
} from "../../domain/models/circuit-group-structure-project-command.model";
|
||||
import type {
|
||||
CircuitGroupRenumberPlan,
|
||||
} from "../../domain/services/circuit-group-renumbering";
|
||||
|
||||
export function toCircuitGroupSnapshot(
|
||||
section: CircuitTreeSectionDto,
|
||||
@@ -115,6 +118,75 @@ export function buildCircuitGroupReorderAssignments(
|
||||
}));
|
||||
}
|
||||
|
||||
export function buildCircuitGroupRenumberPlan(
|
||||
sections: readonly CircuitTreeSectionDto[],
|
||||
category: CircuitGroupCategory
|
||||
): CircuitGroupRenumberPlan | null {
|
||||
const groups = getOrderedCategoryGroups(sections, category);
|
||||
if (!canRenumberCircuitGroups(sections, category)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
groups: groups.map((group, index) => {
|
||||
const targetGroupNumber = index + 1;
|
||||
const expectedPrefix = formatGroupPrefix(
|
||||
category,
|
||||
group.groupNumber
|
||||
);
|
||||
if (group.prefix !== expectedPrefix) {
|
||||
throw new Error(
|
||||
`Das Präfix der Gruppe „${group.displayName}“ passt nicht zu ihrer Gruppennummer.`
|
||||
);
|
||||
}
|
||||
return {
|
||||
groupId: group.id,
|
||||
category,
|
||||
expectedGroupNumber: group.groupNumber,
|
||||
targetGroupNumber,
|
||||
expectedPrefix,
|
||||
targetPrefix: formatGroupPrefix(category, targetGroupNumber),
|
||||
circuits: group.circuits.map((circuit) => {
|
||||
const circuitNumber = parseCircuitNumber(
|
||||
circuit.equipmentIdentifier,
|
||||
category,
|
||||
group.groupNumber
|
||||
);
|
||||
return {
|
||||
circuitId: circuit.id,
|
||||
expectedEquipmentIdentifier: circuit.equipmentIdentifier,
|
||||
targetEquipmentIdentifier: formatCircuitIdentifier(
|
||||
category,
|
||||
targetGroupNumber,
|
||||
circuitNumber
|
||||
),
|
||||
};
|
||||
}),
|
||||
components: group.components.map((component) => ({
|
||||
componentId: component.id,
|
||||
expectedEquipmentIdentifier: component.equipmentIdentifier,
|
||||
targetEquipmentIdentifier: formatGroupComponentIdentifier(
|
||||
category,
|
||||
targetGroupNumber,
|
||||
component.role
|
||||
),
|
||||
})),
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function canRenumberCircuitGroups(
|
||||
sections: readonly CircuitTreeSectionDto[],
|
||||
category: CircuitGroupCategory
|
||||
) {
|
||||
const groups = getOrderedCategoryGroups(sections, category);
|
||||
return (
|
||||
groups.length > 0 &&
|
||||
groups.some((group, index) => group.groupNumber !== index + 1)
|
||||
);
|
||||
}
|
||||
|
||||
function getNewGroupSortOrder(
|
||||
category: CircuitGroupCategory,
|
||||
sections: readonly (CircuitTreeSectionDto & {
|
||||
@@ -141,3 +213,77 @@ function getNewGroupSortOrder(
|
||||
? previous.sortOrder + (next.sortOrder - previous.sortOrder) / 2
|
||||
: previous.sortOrder + 10;
|
||||
}
|
||||
|
||||
function formatGroupPrefix(
|
||||
category: CircuitGroupCategory,
|
||||
groupNumber: number
|
||||
) {
|
||||
return `-${circuitGroupCategoryNumbers[category]}F${groupNumber}.`;
|
||||
}
|
||||
|
||||
function getOrderedCategoryGroups(
|
||||
sections: readonly CircuitTreeSectionDto[],
|
||||
category: CircuitGroupCategory
|
||||
) {
|
||||
return sections
|
||||
.filter(
|
||||
(section): section is CircuitTreeSectionDto & {
|
||||
category: CircuitGroupCategory;
|
||||
groupNumber: number;
|
||||
} =>
|
||||
section.category === category &&
|
||||
Number.isInteger(section.groupNumber) &&
|
||||
(section.groupNumber ?? 0) > 0
|
||||
)
|
||||
.sort(
|
||||
(left, right) =>
|
||||
left.sortOrder - right.sortOrder ||
|
||||
left.id.localeCompare(right.id)
|
||||
);
|
||||
}
|
||||
|
||||
function formatCircuitIdentifier(
|
||||
category: CircuitGroupCategory,
|
||||
groupNumber: number,
|
||||
circuitNumber: number
|
||||
) {
|
||||
return `${formatGroupPrefix(category, groupNumber)}${circuitNumber}`;
|
||||
}
|
||||
|
||||
function parseCircuitNumber(
|
||||
equipmentIdentifier: string,
|
||||
category: CircuitGroupCategory,
|
||||
groupNumber: number
|
||||
) {
|
||||
const prefix = formatGroupPrefix(category, groupNumber);
|
||||
const suffix = equipmentIdentifier.startsWith(prefix)
|
||||
? equipmentIdentifier.slice(prefix.length)
|
||||
: "";
|
||||
const circuitNumber = Number(suffix);
|
||||
if (
|
||||
!/^[1-9]\d*$/.test(suffix) ||
|
||||
!Number.isSafeInteger(circuitNumber)
|
||||
) {
|
||||
throw new Error(
|
||||
`Das Stromkreis-BMK „${equipmentIdentifier}“ passt nicht zu seiner Gruppe.`
|
||||
);
|
||||
}
|
||||
return circuitNumber;
|
||||
}
|
||||
|
||||
function formatGroupComponentIdentifier(
|
||||
category: CircuitGroupCategory,
|
||||
groupNumber: number,
|
||||
role: CircuitTreeSectionDto["components"][number]["role"]
|
||||
) {
|
||||
const categoryNumber = circuitGroupCategoryNumbers[category];
|
||||
if (role === "group_upstream_protection") {
|
||||
return `-${categoryNumber}F${groupNumber}.0`;
|
||||
}
|
||||
if (role === "group_residual_current_protection") {
|
||||
return `-${categoryNumber}Q${groupNumber}.0`;
|
||||
}
|
||||
throw new Error(
|
||||
"Die Stromkreisgruppe enthält eine nicht unterstützte Verteilerkomponente."
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user