complete new audit system
This commit is contained in:
+107
-11
@@ -32,6 +32,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getContracts = getContracts;
|
||||
exports.getContract = getContract;
|
||||
@@ -47,12 +50,12 @@ exports.getCockpit = getCockpit;
|
||||
exports.addSuccessorMeter = addSuccessorMeter;
|
||||
exports.removeContractMeter = removeContractMeter;
|
||||
exports.snoozeContract = snoozeContract;
|
||||
const client_1 = require("@prisma/client");
|
||||
const prisma_js_1 = __importDefault(require("../lib/prisma.js"));
|
||||
const contractService = __importStar(require("../services/contract.service.js"));
|
||||
const contractCockpitService = __importStar(require("../services/contractCockpit.service.js"));
|
||||
const contractHistoryService = __importStar(require("../services/contractHistory.service.js"));
|
||||
const authorizationService = __importStar(require("../services/authorization.service.js"));
|
||||
const prisma = new client_1.PrismaClient();
|
||||
const audit_service_js_1 = require("../services/audit.service.js");
|
||||
async function getContracts(req, res) {
|
||||
try {
|
||||
const { customerId, type, status, search, page, limit, tree } = req.query;
|
||||
@@ -138,6 +141,12 @@ async function getContract(req, res) {
|
||||
async function createContract(req, res) {
|
||||
try {
|
||||
const contract = await contractService.createContract(req.body);
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'CREATE', resourceType: 'Contract',
|
||||
resourceId: contract.id.toString(),
|
||||
label: `Vertrag ${contract.contractNumber} angelegt`,
|
||||
customerId: contract.customerId,
|
||||
});
|
||||
res.status(201).json({ success: true, data: contract });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -149,7 +158,63 @@ async function createContract(req, res) {
|
||||
}
|
||||
async function updateContract(req, res) {
|
||||
try {
|
||||
const contract = await contractService.updateContract(parseInt(req.params.id), req.body);
|
||||
const contractId = parseInt(req.params.id);
|
||||
// Vorherigen Stand laden für Audit-Vergleich
|
||||
const before = await prisma_js_1.default.contract.findUnique({
|
||||
where: { id: contractId },
|
||||
include: { energyDetails: true, internetDetails: true, mobileDetails: true, tvDetails: true, carInsuranceDetails: true },
|
||||
});
|
||||
const contract = await contractService.updateContract(contractId, req.body);
|
||||
// Geänderte Felder ermitteln
|
||||
const changes = {};
|
||||
const fieldLabels = {
|
||||
status: 'Status', startDate: 'Vertragsbeginn', endDate: 'Vertragsende',
|
||||
portalUsername: 'Portal-Benutzername', customerNumberAtProvider: 'Kundennummer beim Anbieter',
|
||||
providerId: 'Anbieter', tariffId: 'Tarif', cancellationPeriodId: 'Kündigungsfrist',
|
||||
contractDurationId: 'Vertragslaufzeit', platformId: 'Vertriebsplattform',
|
||||
cancellationDate: 'Kündigungsdatum', cancellationSentDate: 'Kündigung gesendet am',
|
||||
identityDocumentId: 'Ausweis', bankCardId: 'Bankverbindung', addressId: 'Adresse',
|
||||
commission: 'Provision', notes: 'Notizen',
|
||||
};
|
||||
const energyLabels = {
|
||||
meterId: 'Zähler', maloId: 'MaLo-ID', annualConsumption: 'Jahresverbrauch',
|
||||
basePrice: 'Grundpreis', unitPrice: 'Arbeitspreis', unitPriceNt: 'NT-Arbeitspreis', bonus: 'Bonus',
|
||||
};
|
||||
// Hauptfelder vergleichen
|
||||
const body = req.body;
|
||||
if (before) {
|
||||
for (const [key, newVal] of Object.entries(body)) {
|
||||
if (['energyDetails', 'internetDetails', 'mobileDetails', 'tvDetails', 'carInsuranceDetails', 'password'].includes(key))
|
||||
continue;
|
||||
const oldVal = before[key];
|
||||
const norm = (v) => (v === null || v === undefined || v === '' ? null : v);
|
||||
if (JSON.stringify(norm(oldVal)) !== JSON.stringify(norm(newVal))) {
|
||||
const label = fieldLabels[key] || key;
|
||||
changes[label] = { von: oldVal ?? '-', nach: newVal ?? '-' };
|
||||
}
|
||||
}
|
||||
// Energie-Details vergleichen
|
||||
if (body.energyDetails && before.energyDetails) {
|
||||
for (const [key, newVal] of Object.entries(body.energyDetails)) {
|
||||
const oldVal = before.energyDetails[key];
|
||||
const norm = (v) => (v === null || v === undefined || v === '' ? null : v);
|
||||
if (JSON.stringify(norm(oldVal)) !== JSON.stringify(norm(newVal))) {
|
||||
const label = energyLabels[key] || key;
|
||||
changes[label] = { von: oldVal ?? '-', nach: newVal ?? '-' };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const changeList = Object.entries(changes).map(([f, c]) => `${f}: ${c.von} → ${c.nach}`).join(', ');
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'UPDATE', resourceType: 'Contract',
|
||||
resourceId: contractId.toString(),
|
||||
label: changeList
|
||||
? `Vertrag ${before?.contractNumber || contractId} aktualisiert: ${changeList}`
|
||||
: `Vertrag ${before?.contractNumber || contractId} aktualisiert`,
|
||||
details: Object.keys(changes).length > 0 ? changes : undefined,
|
||||
customerId: before?.customerId,
|
||||
});
|
||||
res.json({ success: true, data: contract });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -161,7 +226,15 @@ async function updateContract(req, res) {
|
||||
}
|
||||
async function deleteContract(req, res) {
|
||||
try {
|
||||
await contractService.deleteContract(parseInt(req.params.id));
|
||||
const contractId = parseInt(req.params.id);
|
||||
const contract = await prisma_js_1.default.contract.findUnique({ where: { id: contractId }, select: { contractNumber: true, customerId: true } });
|
||||
await contractService.deleteContract(contractId);
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'DELETE', resourceType: 'Contract',
|
||||
resourceId: contractId.toString(),
|
||||
label: `Vertrag ${contract?.contractNumber} gelöscht`,
|
||||
customerId: contract?.customerId,
|
||||
});
|
||||
res.json({ success: true, message: 'Vertrag gelöscht' });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -175,7 +248,7 @@ async function createFollowUp(req, res) {
|
||||
try {
|
||||
const previousContractId = parseInt(req.params.id);
|
||||
// Vorgängervertrag laden für Vertragsnummer
|
||||
const previousContract = await prisma.contract.findUnique({
|
||||
const previousContract = await prisma_js_1.default.contract.findUnique({
|
||||
where: { id: previousContractId },
|
||||
select: { contractNumber: true },
|
||||
});
|
||||
@@ -189,6 +262,12 @@ async function createFollowUp(req, res) {
|
||||
await contractHistoryService.createFollowUpHistoryEntry(previousContractId, contract.contractNumber, createdBy);
|
||||
// Historie-Eintrag für den neuen Folgevertrag erstellen
|
||||
await contractHistoryService.createNewContractFromPredecessorEntry(contract.id, previousContract.contractNumber, createdBy);
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'CREATE', resourceType: 'Contract',
|
||||
resourceId: contract.id.toString(),
|
||||
label: `Folgevertrag erstellt für ${previousContract.contractNumber}`,
|
||||
customerId: contract.customerId,
|
||||
});
|
||||
res.status(201).json({ success: true, data: contract });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -272,7 +351,7 @@ async function addSuccessorMeter(req, res) {
|
||||
try {
|
||||
const contractId = parseInt(req.params.id);
|
||||
const { meterId, installedAt, finalReadingPrevious } = req.body;
|
||||
const contract = await prisma.contract.findUnique({
|
||||
const contract = await prisma_js_1.default.contract.findUnique({
|
||||
where: { id: contractId },
|
||||
include: { energyDetails: { include: { contractMeters: { orderBy: { position: 'asc' } } } } },
|
||||
});
|
||||
@@ -288,7 +367,7 @@ async function addSuccessorMeter(req, res) {
|
||||
// Vorherigen Zähler als gewechselt markieren
|
||||
if (existingMeters.length > 0 && finalReadingPrevious !== undefined) {
|
||||
const prevMeter = existingMeters[existingMeters.length - 1];
|
||||
await prisma.contractMeter.update({
|
||||
await prisma_js_1.default.contractMeter.update({
|
||||
where: { id: prevMeter.id },
|
||||
data: {
|
||||
removedAt: installedAt ? new Date(installedAt) : new Date(),
|
||||
@@ -296,7 +375,7 @@ async function addSuccessorMeter(req, res) {
|
||||
},
|
||||
});
|
||||
}
|
||||
const contractMeter = await prisma.contractMeter.create({
|
||||
const contractMeter = await prisma_js_1.default.contractMeter.create({
|
||||
data: {
|
||||
energyContractDetailsId: ecdId,
|
||||
meterId: parseInt(meterId),
|
||||
@@ -306,10 +385,16 @@ async function addSuccessorMeter(req, res) {
|
||||
include: { meter: { include: { readings: true } } },
|
||||
});
|
||||
// Aktuellen Zähler am Vertrag aktualisieren
|
||||
await prisma.energyContractDetails.update({
|
||||
await prisma_js_1.default.energyContractDetails.update({
|
||||
where: { id: ecdId },
|
||||
data: { meterId: parseInt(meterId) },
|
||||
});
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'CREATE', resourceType: 'ContractMeter',
|
||||
resourceId: contractMeter.id.toString(),
|
||||
label: `Folgezähler hinzugefügt zu Vertrag #${contractId}`,
|
||||
customerId: contract.customerId,
|
||||
});
|
||||
res.json({ success: true, data: contractMeter });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -322,7 +407,13 @@ async function addSuccessorMeter(req, res) {
|
||||
async function removeContractMeter(req, res) {
|
||||
try {
|
||||
const contractMeterId = parseInt(req.params.contractMeterId);
|
||||
await prisma.contractMeter.delete({ where: { id: contractMeterId } });
|
||||
const contractId = parseInt(req.params.id);
|
||||
await prisma_js_1.default.contractMeter.delete({ where: { id: contractMeterId } });
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'DELETE', resourceType: 'ContractMeter',
|
||||
resourceId: contractMeterId.toString(),
|
||||
label: `Folgezähler entfernt von Vertrag #${contractId}`,
|
||||
});
|
||||
res.json({ success: true, data: null });
|
||||
}
|
||||
catch (error) {
|
||||
@@ -348,7 +439,7 @@ async function snoozeContract(req, res) {
|
||||
reviewDate.setMonth(reviewDate.getMonth() + months);
|
||||
}
|
||||
// Wenn beides leer → nextReviewDate wird auf null gesetzt (Snooze aufheben)
|
||||
const updated = await prisma.contract.update({
|
||||
const updated = await prisma_js_1.default.contract.update({
|
||||
where: { id },
|
||||
data: { nextReviewDate: reviewDate },
|
||||
select: {
|
||||
@@ -357,6 +448,11 @@ async function snoozeContract(req, res) {
|
||||
nextReviewDate: true,
|
||||
},
|
||||
});
|
||||
await (0, audit_service_js_1.logChange)({
|
||||
req, action: 'UPDATE', resourceType: 'Contract',
|
||||
resourceId: id.toString(),
|
||||
label: `Vertrag ${updated.contractNumber} zurückgestellt`,
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: updated,
|
||||
|
||||
Reference in New Issue
Block a user