diff --git a/backend/src/services/customer.service.ts b/backend/src/services/customer.service.ts
index 918f02d5..45ec1d82 100644
--- a/backend/src/services/customer.service.ts
+++ b/backend/src/services/customer.service.ts
@@ -87,6 +87,24 @@ export async function getCustomerById(id: number) {
readings: {
orderBy: { readingDate: 'desc' },
},
+ // Verträge, die diesen Zähler aktuell als Hauptzähler nutzen
+ // (energyDetails.meterId === meter.id)
+ energyDetails: {
+ include: {
+ contract: { select: { id: true, contractNumber: true, status: true, type: true, providerName: true } },
+ },
+ },
+ // Verträge, in denen der Zähler in der ContractMeter-Kette steht
+ // (Vorgänger oder Nachfolger über Zählerwechsel)
+ contractMeters: {
+ include: {
+ energyContractDetails: {
+ include: {
+ contract: { select: { id: true, contractNumber: true, status: true, type: true, providerName: true } },
+ },
+ },
+ },
+ },
},
},
stressfreiEmails: { orderBy: { isActive: 'desc' } },
diff --git a/frontend/src/pages/customers/CustomerDetail.tsx b/frontend/src/pages/customers/CustomerDetail.tsx
index 85524f4a..50f56505 100644
--- a/frontend/src/pages/customers/CustomerDetail.tsx
+++ b/frontend/src/pages/customers/CustomerDetail.tsx
@@ -1267,6 +1267,7 @@ function MetersTab({
const hasDeliveryAddress = addresses.some((a) => a.type === 'DELIVERY_RESIDENCE');
const [showReadingModal, setShowReadingModal] = useState<{ meterId: number; meterType: 'ELECTRICITY' | 'GAS'; tariffModel?: string } | null>(null);
const [expandedMeter, setExpandedMeter] = useState(null);
+ const [expandedContractsForMeter, setExpandedContractsForMeter] = useState>(new Set());
const [editingReading, setEditingReading] = useState<{ meterId: number; meterType: 'ELECTRICITY' | 'GAS'; tariffModel?: string; reading: any } | null>(null);
const queryClient = useQueryClient();
@@ -1441,6 +1442,77 @@ function MetersTab({
)}
+ {(() => {
+ // Zugeordnete Verträge zusammenstellen: zum einen über
+ // energyDetails (aktueller Hauptzähler), zum anderen über
+ // contractMeters (Folgezähler-Kette). Dedupliziert auf
+ // contractId, da ein Zähler über beide Wege auftauchen kann.
+ const seen = new Set();
+ const linkedContracts: Array<{ id: number; contractNumber: string; status: string; type: string; providerName?: string; via: 'main' | 'chain' }> = [];
+ for (const ed of meter.energyDetails || []) {
+ if (ed.contract && !seen.has(ed.contract.id)) {
+ seen.add(ed.contract.id);
+ linkedContracts.push({ ...ed.contract, via: 'main' });
+ }
+ }
+ for (const cm of meter.contractMeters || []) {
+ const ct = cm.energyContractDetails?.contract;
+ if (ct && !seen.has(ct.id)) {
+ seen.add(ct.id);
+ linkedContracts.push({ ...ct, via: 'chain' });
+ }
+ }
+ if (linkedContracts.length === 0) return null;
+ const isContractsExpanded = expandedContractsForMeter.has(meter.id);
+ return (
+
+
+ {isContractsExpanded && (
+
+ {linkedContracts.map((ct) => (
+
+
+ {ct.contractNumber}
+ {ct.providerName && (
+ – {ct.providerName}
+ )}
+ {ct.status}
+ {ct.via === 'chain' && (
+ (über Folgezähler-Kette)
+ )}
+
+ ))}
+
+ )}
+
+ );
+ })()}
+
{sortedReadings.length > 0 && (
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
index e0f45c48..67045355 100644
--- a/frontend/src/types/index.ts
+++ b/frontend/src/types/index.ts
@@ -221,6 +221,38 @@ export interface Meter {
addressId?: number | null;
address?: Address;
readings?: MeterReading[];
+ // Verträge, die diesen Zähler aktuell als Hauptzähler nutzen
+ energyDetails?: Array<{
+ id: number;
+ contractId: number;
+ contract?: {
+ id: number;
+ contractNumber: string;
+ status: ContractStatus;
+ type: string;
+ providerName?: string;
+ };
+ }>;
+ // Verträge, in denen der Zähler in der ContractMeter-Kette steht
+ // (Vorgänger oder Nachfolger über Zählerwechsel)
+ contractMeters?: Array<{
+ id: number;
+ energyContractDetailsId: number;
+ position: number;
+ installedAt?: string;
+ removedAt?: string;
+ energyContractDetails?: {
+ id: number;
+ contractId: number;
+ contract?: {
+ id: number;
+ contractNumber: string;
+ status: ContractStatus;
+ type: string;
+ providerName?: string;
+ };
+ };
+ }>;
}
export interface ContractMeter {