Datenschutz vollmacht fixed, two time counter added
This commit is contained in:
+620
-458
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
+32
-2
@@ -122,14 +122,14 @@ async function getContractById(id, decryptPassword = false) {
|
||||
previousProvider: true,
|
||||
previousContract: {
|
||||
include: {
|
||||
energyDetails: { include: { meter: { include: { readings: true } }, invoices: true } },
|
||||
energyDetails: { include: { meter: { include: { readings: true } }, contractMeters: { include: { meter: { include: { readings: true } } }, orderBy: { position: 'asc' } }, invoices: true } },
|
||||
internetDetails: { include: { phoneNumbers: true } },
|
||||
mobileDetails: { include: { simCards: true } },
|
||||
tvDetails: true,
|
||||
carInsuranceDetails: true,
|
||||
},
|
||||
},
|
||||
energyDetails: { include: { meter: { include: { readings: true } }, invoices: true } },
|
||||
energyDetails: { include: { meter: { include: { readings: true } }, contractMeters: { include: { meter: { include: { readings: true } } }, orderBy: { position: 'asc' } }, invoices: true } },
|
||||
internetDetails: { include: { phoneNumbers: true } },
|
||||
mobileDetails: { include: { simCards: true } },
|
||||
tvDetails: true,
|
||||
@@ -264,11 +264,41 @@ async function updateContract(id, data) {
|
||||
});
|
||||
// Update type-specific details
|
||||
if (energyDetails) {
|
||||
const existingEcd = await prisma.energyContractDetails.findUnique({
|
||||
where: { contractId: id },
|
||||
select: { id: true, meterId: true },
|
||||
});
|
||||
await prisma.energyContractDetails.upsert({
|
||||
where: { contractId: id },
|
||||
update: energyDetails,
|
||||
create: { contractId: id, ...energyDetails },
|
||||
});
|
||||
// ContractMeter synchronisieren wenn sich der Zähler ändert
|
||||
if (energyDetails.meterId !== undefined && existingEcd) {
|
||||
const oldMeterId = existingEcd.meterId;
|
||||
const newMeterId = energyDetails.meterId;
|
||||
if (oldMeterId !== newMeterId) {
|
||||
// Alle alten ContractMeter-Einträge entfernen
|
||||
await prisma.contractMeter.deleteMany({
|
||||
where: { energyContractDetailsId: existingEcd.id },
|
||||
});
|
||||
// Neuen ContractMeter-Eintrag erstellen (wenn ein Zähler gesetzt)
|
||||
if (newMeterId) {
|
||||
const contract = await prisma.contract.findUnique({
|
||||
where: { id },
|
||||
select: { startDate: true },
|
||||
});
|
||||
await prisma.contractMeter.create({
|
||||
data: {
|
||||
energyContractDetailsId: existingEcd.id,
|
||||
meterId: newMeterId,
|
||||
position: 0,
|
||||
installedAt: contract?.startDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (internetDetails) {
|
||||
const { phoneNumbers, internetPassword, ...internetData } = internetDetails;
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -78,6 +78,10 @@ export interface ReportedMeterReading {
|
||||
customerNumber: string;
|
||||
name: string;
|
||||
};
|
||||
contract?: {
|
||||
id: number;
|
||||
contractNumber: string;
|
||||
};
|
||||
providerPortal?: {
|
||||
providerName: string;
|
||||
portalUrl: string;
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"contractCockpit.service.d.ts","sourceRoot":"","sources":["../../src/services/contractCockpit.service.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"contractCockpit.service.d.ts","sourceRoot":"","sources":["../../src/services/contractCockpit.service.ts"],"names":[],"mappings":"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"}
|
||||
@@ -682,6 +682,7 @@ async function getReportedMeterReadings() {
|
||||
contract: {
|
||||
select: {
|
||||
id: true,
|
||||
contractNumber: true,
|
||||
portalUsername: true,
|
||||
provider: {
|
||||
select: { id: true, name: true, portalUrl: true },
|
||||
@@ -717,6 +718,10 @@ async function getReportedMeterReadings() {
|
||||
customerNumber: r.meter.customer.customerNumber,
|
||||
name: `${r.meter.customer.firstName} ${r.meter.customer.lastName}`,
|
||||
},
|
||||
contract: contract ? {
|
||||
id: contract.id,
|
||||
contractNumber: contract.contractNumber,
|
||||
} : undefined,
|
||||
providerPortal: provider?.portalUrl ? {
|
||||
providerName: provider.name,
|
||||
portalUrl: provider.portalUrl,
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+7
-7
@@ -206,17 +206,17 @@ export declare function getAllTasks(filters: AllTasksFilters): Promise<({
|
||||
customerNumber: string;
|
||||
companyName: string | null;
|
||||
};
|
||||
tariff: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
contractNumber: string;
|
||||
providerName: string | null;
|
||||
tariffName: string | null;
|
||||
provider: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
tariffName: string | null;
|
||||
providerName: string | null;
|
||||
contractNumber: string;
|
||||
tariff: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
};
|
||||
subtasks: {
|
||||
id: number;
|
||||
|
||||
+29
-16
@@ -107,13 +107,14 @@ export declare function getCustomerById(id: number): Promise<({
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}[];
|
||||
} & {
|
||||
id: number;
|
||||
@@ -123,6 +124,7 @@ export declare function getCustomerById(id: number): Promise<({
|
||||
updatedAt: Date;
|
||||
type: import(".prisma/client").$Enums.MeterType;
|
||||
meterNumber: string;
|
||||
tariffModel: import(".prisma/client").$Enums.MeterTariffModel;
|
||||
location: string | null;
|
||||
})[];
|
||||
stressfreiEmails: {
|
||||
@@ -171,11 +173,8 @@ export declare function getCustomerById(id: number): Promise<({
|
||||
notes: string | null;
|
||||
portalPasswordEncrypted: string | null;
|
||||
startDate: Date | null;
|
||||
status: import(".prisma/client").$Enums.ContractStatus;
|
||||
customerNumberAtProvider: string | null;
|
||||
tariffName: string | null;
|
||||
providerName: string | null;
|
||||
contractNumber: string;
|
||||
status: import(".prisma/client").$Enums.ContractStatus;
|
||||
contractCategoryId: number | null;
|
||||
addressId: number | null;
|
||||
billingAddressId: number | null;
|
||||
@@ -190,6 +189,9 @@ export declare function getCustomerById(id: number): Promise<({
|
||||
previousContractNumber: string | null;
|
||||
providerId: number | null;
|
||||
tariffId: number | null;
|
||||
providerName: string | null;
|
||||
tariffName: string | null;
|
||||
customerNumberAtProvider: string | null;
|
||||
contractNumberAtProvider: string | null;
|
||||
priceFirst12Months: string | null;
|
||||
priceFrom13Months: string | null;
|
||||
@@ -573,13 +575,14 @@ export declare function getCustomerMeters(customerId: number, showInactive?: boo
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}[];
|
||||
} & {
|
||||
id: number;
|
||||
@@ -589,6 +592,7 @@ export declare function getCustomerMeters(customerId: number, showInactive?: boo
|
||||
updatedAt: Date;
|
||||
type: import(".prisma/client").$Enums.MeterType;
|
||||
meterNumber: string;
|
||||
tariffModel: import(".prisma/client").$Enums.MeterTariffModel;
|
||||
location: string | null;
|
||||
})[]>;
|
||||
export declare function createMeter(customerId: number, data: {
|
||||
@@ -603,6 +607,7 @@ export declare function createMeter(customerId: number, data: {
|
||||
updatedAt: Date;
|
||||
type: import(".prisma/client").$Enums.MeterType;
|
||||
meterNumber: string;
|
||||
tariffModel: import(".prisma/client").$Enums.MeterTariffModel;
|
||||
location: string | null;
|
||||
}>;
|
||||
export declare function updateMeter(id: number, data: {
|
||||
@@ -618,6 +623,7 @@ export declare function updateMeter(id: number, data: {
|
||||
updatedAt: Date;
|
||||
type: import(".prisma/client").$Enums.MeterType;
|
||||
meterNumber: string;
|
||||
tariffModel: import(".prisma/client").$Enums.MeterTariffModel;
|
||||
location: string | null;
|
||||
}>;
|
||||
export declare function deleteMeter(id: number): Promise<{
|
||||
@@ -628,11 +634,13 @@ export declare function deleteMeter(id: number): Promise<{
|
||||
updatedAt: Date;
|
||||
type: import(".prisma/client").$Enums.MeterType;
|
||||
meterNumber: string;
|
||||
tariffModel: import(".prisma/client").$Enums.MeterTariffModel;
|
||||
location: string | null;
|
||||
}>;
|
||||
export declare function addMeterReading(meterId: number, data: {
|
||||
readingDate: Date;
|
||||
value: number;
|
||||
valueNt?: number;
|
||||
unit?: string;
|
||||
notes?: string;
|
||||
}): Promise<{
|
||||
@@ -640,30 +648,33 @@ export declare function addMeterReading(meterId: number, data: {
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}>;
|
||||
export declare function getMeterReadings(meterId: number): Promise<{
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}[]>;
|
||||
export declare function updateMeterReading(meterId: number, readingId: number, data: {
|
||||
readingDate?: Date;
|
||||
value?: number;
|
||||
valueNt?: number | null;
|
||||
unit?: string;
|
||||
notes?: string;
|
||||
}): Promise<{
|
||||
@@ -671,26 +682,28 @@ export declare function updateMeterReading(meterId: number, readingId: number, d
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}>;
|
||||
export declare function deleteMeterReading(meterId: number, readingId: number): Promise<{
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
notes: string | null;
|
||||
readingDate: Date;
|
||||
meterId: number;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
value: number;
|
||||
valueNt: number | null;
|
||||
unit: string;
|
||||
reportedBy: string | null;
|
||||
status: import(".prisma/client").$Enums.MeterReadingStatus;
|
||||
transferredAt: Date | null;
|
||||
transferredBy: string | null;
|
||||
meterId: number;
|
||||
}>;
|
||||
export declare function updatePortalSettings(customerId: number, data: {
|
||||
portalEnabled?: boolean;
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+65
-1
@@ -321,13 +321,42 @@ async function updateMeter(id, data) {
|
||||
});
|
||||
}
|
||||
async function deleteMeter(id) {
|
||||
// Prüfen ob der Zähler noch an Verträgen hängt
|
||||
const linkedContracts = await prisma.contractMeter.findMany({
|
||||
where: { meterId: id },
|
||||
include: { energyContractDetails: { include: { contract: { select: { contractNumber: true } } } } },
|
||||
});
|
||||
if (linkedContracts.length > 0) {
|
||||
const contractNumbers = linkedContracts
|
||||
.map(cm => cm.energyContractDetails.contract.contractNumber)
|
||||
.join(', ');
|
||||
throw new Error(`Zähler kann nicht gelöscht werden – noch an Vertrag/Verträgen zugeordnet: ${contractNumbers}`);
|
||||
}
|
||||
// Auch direkte meterId-Referenz auf EnergyContractDetails prüfen
|
||||
const directLinks = await prisma.energyContractDetails.findMany({
|
||||
where: { meterId: id },
|
||||
include: { contract: { select: { contractNumber: true } } },
|
||||
});
|
||||
if (directLinks.length > 0) {
|
||||
const contractNumbers = directLinks.map(d => d.contract.contractNumber).join(', ');
|
||||
throw new Error(`Zähler kann nicht gelöscht werden – noch an Vertrag/Verträgen zugeordnet: ${contractNumbers}`);
|
||||
}
|
||||
return prisma.meter.delete({ where: { id } });
|
||||
}
|
||||
async function addMeterReading(meterId, data) {
|
||||
// Validierung: Zählerstand muss monoton steigend sein
|
||||
await validateReadingValue(meterId, data.readingDate, data.value, undefined, 'HT');
|
||||
if (data.valueNt !== undefined) {
|
||||
await validateReadingValue(meterId, data.readingDate, data.valueNt, undefined, 'NT');
|
||||
}
|
||||
return prisma.meterReading.create({
|
||||
data: {
|
||||
meterId,
|
||||
...data,
|
||||
readingDate: data.readingDate,
|
||||
value: data.value,
|
||||
valueNt: data.valueNt,
|
||||
unit: data.unit,
|
||||
notes: data.notes,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -345,11 +374,46 @@ async function updateMeterReading(meterId, readingId, data) {
|
||||
if (!reading) {
|
||||
throw new Error('Zählerstand nicht gefunden');
|
||||
}
|
||||
// Validierung bei Wertänderung
|
||||
if (data.value !== undefined || data.readingDate !== undefined) {
|
||||
await validateReadingValue(meterId, data.readingDate || reading.readingDate, data.value ?? reading.value, readingId, 'HT');
|
||||
}
|
||||
if (data.valueNt !== undefined || data.readingDate !== undefined) {
|
||||
const ntVal = data.valueNt ?? reading.valueNt;
|
||||
if (ntVal !== undefined && ntVal !== null) {
|
||||
await validateReadingValue(meterId, data.readingDate || reading.readingDate, ntVal, readingId, 'NT');
|
||||
}
|
||||
}
|
||||
return prisma.meterReading.update({
|
||||
where: { id: readingId },
|
||||
data,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Validiert, dass ein Zählerstand monoton steigend ist.
|
||||
* tariffLabel: 'HT' für Hochtarif/Eintarif, 'NT' für Niedertarif
|
||||
*/
|
||||
async function validateReadingValue(meterId, readingDate, value, excludeReadingId, tariffLabel = 'HT') {
|
||||
const existing = await prisma.meterReading.findMany({
|
||||
where: { meterId, ...(excludeReadingId ? { id: { not: excludeReadingId } } : {}) },
|
||||
orderBy: { readingDate: 'asc' },
|
||||
});
|
||||
const fmtDate = (d) => d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||
const fmtVal = (v) => v.toLocaleString('de-DE');
|
||||
const label = tariffLabel === 'NT' ? 'NT-Zählerstand' : 'Zählerstand';
|
||||
// Vergleichswert aus bestehendem Reading extrahieren
|
||||
const getVal = (r) => tariffLabel === 'NT' ? (r.valueNt ?? 0) : r.value;
|
||||
// Stand vor dem neuen Datum
|
||||
const before = [...existing].filter(r => r.readingDate <= readingDate).pop();
|
||||
if (before && value < getVal(before)) {
|
||||
throw new Error(`${label} (${fmtVal(value)}) darf nicht kleiner sein als der Stand vom ${fmtDate(before.readingDate)} (${fmtVal(getVal(before))})`);
|
||||
}
|
||||
// Stand nach dem neuen Datum
|
||||
const after = existing.find(r => r.readingDate > readingDate);
|
||||
if (after && value > getVal(after)) {
|
||||
throw new Error(`${label} (${fmtVal(value)}) darf nicht größer sein als der spätere Stand vom ${fmtDate(after.readingDate)} (${fmtVal(getVal(after))})`);
|
||||
}
|
||||
}
|
||||
async function deleteMeterReading(meterId, readingId) {
|
||||
// Verify the reading belongs to the meter
|
||||
const reading = await prisma.meterReading.findFirst({
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user