Datenschutz vollmacht fixed, two time counter added
This commit is contained in:
@@ -11,5 +11,7 @@ export declare function getSimCardCredentials(req: Request, res: Response): Prom
|
||||
export declare function getInternetCredentials(req: Request, res: Response): Promise<void>;
|
||||
export declare function getSipCredentials(req: Request, res: Response): Promise<void>;
|
||||
export declare function getCockpit(req: AuthRequest, res: Response): Promise<void>;
|
||||
export declare function addSuccessorMeter(req: AuthRequest, res: Response): Promise<void>;
|
||||
export declare function removeContractMeter(req: AuthRequest, res: Response): Promise<void>;
|
||||
export declare function snoozeContract(req: Request, res: Response): Promise<void>;
|
||||
//# sourceMappingURL=contract.controller.d.ts.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"contract.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/contract.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM5C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI7D,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDjF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCnF;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAID,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC/E"}
|
||||
{"version":3,"file":"contract.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/contract.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM5C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI7D,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDjF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCnF;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAID,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDtF;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxF;AAID,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC/E"}
|
||||
+67
@@ -44,6 +44,8 @@ exports.getSimCardCredentials = getSimCardCredentials;
|
||||
exports.getInternetCredentials = getInternetCredentials;
|
||||
exports.getSipCredentials = getSipCredentials;
|
||||
exports.getCockpit = getCockpit;
|
||||
exports.addSuccessorMeter = addSuccessorMeter;
|
||||
exports.removeContractMeter = removeContractMeter;
|
||||
exports.snoozeContract = snoozeContract;
|
||||
const client_1 = require("@prisma/client");
|
||||
const contractService = __importStar(require("../services/contract.service.js"));
|
||||
@@ -265,6 +267,71 @@ async function getCockpit(req, res) {
|
||||
});
|
||||
}
|
||||
}
|
||||
// ==================== FOLGEZÄHLER ====================
|
||||
async function addSuccessorMeter(req, res) {
|
||||
try {
|
||||
const contractId = parseInt(req.params.id);
|
||||
const { meterId, installedAt, finalReadingPrevious } = req.body;
|
||||
const contract = await prisma.contract.findUnique({
|
||||
where: { id: contractId },
|
||||
include: { energyDetails: { include: { contractMeters: { orderBy: { position: 'asc' } } } } },
|
||||
});
|
||||
if (!contract?.energyDetails) {
|
||||
res.status(404).json({ success: false, error: 'Energievertrag nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
const ecdId = contract.energyDetails.id;
|
||||
const existingMeters = contract.energyDetails.contractMeters;
|
||||
const nextPosition = existingMeters.length > 0
|
||||
? Math.max(...existingMeters.map(m => m.position)) + 1
|
||||
: 0;
|
||||
// Vorherigen Zähler als gewechselt markieren
|
||||
if (existingMeters.length > 0 && finalReadingPrevious !== undefined) {
|
||||
const prevMeter = existingMeters[existingMeters.length - 1];
|
||||
await prisma.contractMeter.update({
|
||||
where: { id: prevMeter.id },
|
||||
data: {
|
||||
removedAt: installedAt ? new Date(installedAt) : new Date(),
|
||||
finalReading: parseFloat(finalReadingPrevious),
|
||||
},
|
||||
});
|
||||
}
|
||||
const contractMeter = await prisma.contractMeter.create({
|
||||
data: {
|
||||
energyContractDetailsId: ecdId,
|
||||
meterId: parseInt(meterId),
|
||||
position: nextPosition,
|
||||
installedAt: installedAt ? new Date(installedAt) : new Date(),
|
||||
},
|
||||
include: { meter: { include: { readings: true } } },
|
||||
});
|
||||
// Aktuellen Zähler am Vertrag aktualisieren
|
||||
await prisma.energyContractDetails.update({
|
||||
where: { id: ecdId },
|
||||
data: { meterId: parseInt(meterId) },
|
||||
});
|
||||
res.json({ success: true, data: contractMeter });
|
||||
}
|
||||
catch (error) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Fehler beim Hinzufügen des Folgezählers',
|
||||
});
|
||||
}
|
||||
}
|
||||
async function removeContractMeter(req, res) {
|
||||
try {
|
||||
const contractMeterId = parseInt(req.params.contractMeterId);
|
||||
await prisma.contractMeter.delete({ where: { id: contractMeterId } });
|
||||
res.json({ success: true, data: null });
|
||||
}
|
||||
catch (error) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Fehler beim Entfernen',
|
||||
});
|
||||
}
|
||||
}
|
||||
// ==================== SNOOZE (VERTRAG ZURÜCKSTELLEN) ====================
|
||||
async function snoozeContract(req, res) {
|
||||
try {
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"customer.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/customer.controller.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"customer.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/customer.controller.ts"],"names":[],"mappings":"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"}
|
||||
+33
-11
@@ -351,7 +351,14 @@ async function getMeterReadings(req, res) {
|
||||
}
|
||||
async function addMeterReading(req, res) {
|
||||
try {
|
||||
const reading = await customerService.addMeterReading(parseInt(req.params.meterId), req.body);
|
||||
const { readingDate, value, valueNt, unit, notes } = req.body;
|
||||
const reading = await customerService.addMeterReading(parseInt(req.params.meterId), {
|
||||
readingDate: new Date(readingDate),
|
||||
value: parseFloat(value),
|
||||
valueNt: valueNt !== undefined && valueNt !== null && valueNt !== '' ? parseFloat(valueNt) : undefined,
|
||||
unit,
|
||||
notes,
|
||||
});
|
||||
res.status(201).json({ success: true, data: reading });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -363,7 +370,19 @@ async function addMeterReading(req, res) {
|
||||
}
|
||||
async function updateMeterReading(req, res) {
|
||||
try {
|
||||
const reading = await customerService.updateMeterReading(parseInt(req.params.meterId), parseInt(req.params.readingId), req.body);
|
||||
const { readingDate, value, valueNt, unit, notes } = req.body;
|
||||
const updateData = {};
|
||||
if (readingDate !== undefined)
|
||||
updateData.readingDate = new Date(readingDate);
|
||||
if (value !== undefined)
|
||||
updateData.value = parseFloat(value);
|
||||
if (valueNt !== undefined)
|
||||
updateData.valueNt = valueNt !== null && valueNt !== '' ? parseFloat(valueNt) : null;
|
||||
if (unit !== undefined)
|
||||
updateData.unit = unit;
|
||||
if (notes !== undefined)
|
||||
updateData.notes = notes;
|
||||
const reading = await customerService.updateMeterReading(parseInt(req.params.meterId), parseInt(req.params.readingId), updateData);
|
||||
res.json({ success: true, data: reading });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -404,15 +423,18 @@ async function reportMeterReading(req, res) {
|
||||
res.status(403).json({ success: false, error: 'Kein Zugriff auf diesen Zähler' });
|
||||
return;
|
||||
}
|
||||
const reading = await prisma.meterReading.create({
|
||||
data: {
|
||||
meterId,
|
||||
value: parseFloat(value),
|
||||
readingDate: readingDate ? new Date(readingDate) : new Date(),
|
||||
notes,
|
||||
reportedBy: user.email,
|
||||
status: 'REPORTED',
|
||||
},
|
||||
const parsedDate = readingDate ? new Date(readingDate) : new Date();
|
||||
const parsedValue = parseFloat(value);
|
||||
// Validierung über den Service (monoton steigend)
|
||||
const reading = await customerService.addMeterReading(meterId, {
|
||||
readingDate: parsedDate,
|
||||
value: parsedValue,
|
||||
notes,
|
||||
});
|
||||
// Status auf REPORTED setzen
|
||||
await prisma.meterReading.update({
|
||||
where: { id: reading.id },
|
||||
data: { reportedBy: user.email, status: 'REPORTED' },
|
||||
});
|
||||
res.status(201).json({ success: true, data: reading });
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"contract.routes.d.ts","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA8BxB,eAAe,MAAM,CAAC"}
|
||||
{"version":3,"file":"contract.routes.d.ts","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAkCxB,eAAe,MAAM,CAAC"}
|
||||
+3
@@ -48,6 +48,9 @@ router.delete('/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('
|
||||
router.post('/:id/follow-up', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:create'), contractController.createFollowUp);
|
||||
// Snooze (Vertrag zurückstellen)
|
||||
router.patch('/:id/snooze', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), contractController.snoozeContract);
|
||||
// Folgezähler
|
||||
router.post('/:id/successor-meter', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), contractController.addSuccessorMeter);
|
||||
router.delete('/:id/contract-meter/:contractMeterId', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), contractController.removeContractMeter);
|
||||
// Get decrypted password
|
||||
router.get('/:id/password', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:read'), contractController.getContractPassword);
|
||||
// Get decrypted SimCard PIN/PUK
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"contract.routes.js","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAiC;AACjC,0FAA4E;AAC5E,mDAAwE;AAExE,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;AACpG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEzG,2CAA2C;AAC3C,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAEzG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;AACtG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC3G,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE9G,qBAAqB;AACrB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEtH,iCAAiC;AACjC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEpH,yBAAyB;AACzB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAEvH,gCAAgC;AAChC,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;AAE3I,kCAAkC;AAClC,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;AAEtI,6BAA6B;AAC7B,MAAM,CAAC,GAAG,CAAC,6CAA6C,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAEnJ,kBAAe,MAAM,CAAC"}
|
||||
{"version":3,"file":"contract.routes.js","sourceRoot":"","sources":["../../src/routes/contract.routes.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAiC;AACjC,0FAA4E;AAC5E,mDAAwE;AAExE,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;AACpG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEzG,2CAA2C;AAC3C,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAEzG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;AACtG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC3G,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE9G,qBAAqB;AACrB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEtH,iCAAiC;AACjC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAEpH,cAAc;AACd,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAC/H,MAAM,CAAC,MAAM,CAAC,sCAAsC,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAEnJ,yBAAyB;AACzB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAEvH,gCAAgC;AAChC,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;AAE3I,kCAAkC;AAClC,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;AAEtI,6BAA6B;AAC7B,MAAM,CAAC,GAAG,CAAC,6CAA6C,EAAE,sBAAY,EAAE,IAAA,2BAAiB,EAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAEnJ,kBAAe,MAAM,CAAC"}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"upload.routes.d.ts","sourceRoot":"","sources":["../../src/routes/upload.routes.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2uBxB,eAAe,MAAM,CAAC"}
|
||||
{"version":3,"file":"upload.routes.d.ts","sourceRoot":"","sources":["../../src/routes/upload.routes.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2vBxB,eAAe,MAAM,CAAC"}
|
||||
Vendored
+14
@@ -338,6 +338,15 @@ router.post('/customers/:id/privacy-policy', auth_js_1.authenticate, (0, auth_js
|
||||
where: { id: customerId },
|
||||
data: { privacyPolicyPath: relativePath },
|
||||
});
|
||||
// Alle Consents auf GRANTED setzen (PDF = vollständige Einwilligung)
|
||||
const consentTypes = ['DATA_PROCESSING', 'MARKETING_EMAIL', 'MARKETING_PHONE', 'DATA_SHARING_PARTNER'];
|
||||
for (const consentType of consentTypes) {
|
||||
await prisma.customerConsent.upsert({
|
||||
where: { customerId_consentType: { customerId, consentType } },
|
||||
update: { status: 'GRANTED', grantedAt: new Date(), source: 'papier' },
|
||||
create: { customerId, consentType, status: 'GRANTED', grantedAt: new Date(), source: 'papier', createdBy: req.user?.email || 'admin' },
|
||||
});
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
@@ -376,6 +385,11 @@ router.delete('/customers/:id/privacy-policy', auth_js_1.authenticate, (0, auth_
|
||||
where: { id: customerId },
|
||||
data: { privacyPolicyPath: null },
|
||||
});
|
||||
// Nur Consents widerrufen die per Papier erteilt wurden
|
||||
await prisma.customerConsent.updateMany({
|
||||
where: { customerId, status: 'GRANTED', source: 'papier' },
|
||||
data: { status: 'WITHDRAWN', withdrawnAt: new Date() },
|
||||
});
|
||||
res.json({ success: true });
|
||||
}
|
||||
catch (error) {
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+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