Files
leistungsbilanz-ts/src/domain/services/circuit-group-move-planning.ts
T
2026-07-30 19:58:45 +02:00

98 lines
2.8 KiB
TypeScript

import type { CircuitGroupCategory } from "../../shared/constants/circuit-group.js";
import {
formatCircuitGroupPrefix,
getNextGroupedCircuitIdentifier,
parseGroupedEquipmentIdentifier,
} from "./circuit-group-numbering.js";
export interface CircuitMoveGroupIdentity {
id: string;
category: CircuitGroupCategory;
groupNumber: number;
prefix: string;
}
export interface CircuitGroupMovePlan {
circuitId: string;
circuitListId: string;
expectedSectionId: string;
targetSectionId: string;
expectedEquipmentIdentifier: string;
targetEquipmentIdentifier: string;
expectedSortOrder: number;
targetSortOrder: number;
}
export function createCircuitGroupMovePlan(input: {
circuit: {
id: string;
circuitListId: string;
sectionId: string;
equipmentIdentifier: string;
sortOrder: number;
};
sourceGroup: CircuitMoveGroupIdentity;
targetGroup: CircuitMoveGroupIdentity;
targetCircuitEquipmentIdentifiers: Iterable<string>;
targetSortOrder: number;
}): CircuitGroupMovePlan {
assertGroupIdentity(input.sourceGroup);
assertGroupIdentity(input.targetGroup);
if (
input.sourceGroup.id === input.targetGroup.id ||
input.sourceGroup.category !== input.targetGroup.category
) {
throw new Error(
"Circuits can move only between different groups of the same category."
);
}
if (
input.circuit.sectionId !== input.sourceGroup.id ||
!input.circuit.id.trim() ||
!input.circuit.circuitListId.trim() ||
!Number.isFinite(input.circuit.sortOrder) ||
!Number.isFinite(input.targetSortOrder)
) {
throw new Error("Circuit move source or target position is invalid.");
}
const parsed = parseGroupedEquipmentIdentifier(
input.circuit.equipmentIdentifier
);
if (
parsed?.kind !== "circuit" ||
parsed.category !== input.sourceGroup.category ||
parsed.groupNumber !== input.sourceGroup.groupNumber
) {
throw new Error("Circuit BMK does not match its source group.");
}
return {
circuitId: input.circuit.id,
circuitListId: input.circuit.circuitListId,
expectedSectionId: input.sourceGroup.id,
targetSectionId: input.targetGroup.id,
expectedEquipmentIdentifier:
input.circuit.equipmentIdentifier,
targetEquipmentIdentifier:
getNextGroupedCircuitIdentifier(
input.targetGroup.category,
input.targetGroup.groupNumber,
input.targetCircuitEquipmentIdentifiers
),
expectedSortOrder: input.circuit.sortOrder,
targetSortOrder: input.targetSortOrder,
};
}
function assertGroupIdentity(group: CircuitMoveGroupIdentity) {
if (
!group.id.trim() ||
!Number.isInteger(group.groupNumber) ||
group.groupNumber < 1 ||
group.prefix !==
formatCircuitGroupPrefix(group.category, group.groupNumber)
) {
throw new Error("Circuit move group identity is invalid.");
}
}