"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = require("express"); const multer_1 = __importDefault(require("multer")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const client_1 = require("@prisma/client"); const auth_js_1 = require("../middleware/auth.js"); const router = (0, express_1.Router)(); const prisma = new client_1.PrismaClient(); // Uploads-Verzeichnis erstellen falls nicht vorhanden const uploadsDir = path_1.default.join(process.cwd(), 'uploads'); if (!fs_1.default.existsSync(uploadsDir)) { fs_1.default.mkdirSync(uploadsDir, { recursive: true }); } // Multer-Konfiguration const storage = multer_1.default.diskStorage({ destination: (req, file, cb) => { const subDir = req.uploadSubDir || 'misc'; const targetDir = path_1.default.join(uploadsDir, subDir); if (!fs_1.default.existsSync(targetDir)) { fs_1.default.mkdirSync(targetDir, { recursive: true }); } cb(null, targetDir); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); const ext = path_1.default.extname(file.originalname); cb(null, `${uniqueSuffix}${ext}`); }, }); const fileFilter = (req, file, cb) => { // Nur PDFs und Bilder erlauben const allowedTypes = ['application/pdf', 'image/jpeg', 'image/png', 'image/jpg']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Nur PDF, JPG und PNG Dateien sind erlaubt')); } }; const upload = (0, multer_1.default)({ storage, fileFilter, limits: { fileSize: 10 * 1024 * 1024, // 10MB max }, }); // Middleware um Subdirectory zu setzen function setUploadDir(subDir) { return (req, res, next) => { req.uploadSubDir = subDir; next(); }; } // Upload für Bankkarten-Dokumente router.post('/bank-cards/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), setUploadDir('bank-cards'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const bankCardId = parseInt(req.params.id); const relativePath = `/uploads/bank-cards/${req.file.filename}`; // Bankkarte in der DB aktualisieren await prisma.bankCard.update({ where: { id: bankCardId }, data: { documentPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Upload für Ausweis-Dokumente router.post('/documents/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), setUploadDir('documents'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const documentId = parseInt(req.params.id); const relativePath = `/uploads/documents/${req.file.filename}`; // Ausweis in der DB aktualisieren await prisma.identityDocument.update({ where: { id: documentId }, data: { documentPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Löschen von Bankkarten-Dokumenten router.delete('/bank-cards/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), async (req, res) => { try { const bankCardId = parseInt(req.params.id); // Bankkarte aus DB holen um Dateipfad zu bekommen const bankCard = await prisma.bankCard.findUnique({ where: { id: bankCardId }, }); if (!bankCard) { res.status(404).json({ success: false, error: 'Bankkarte nicht gefunden' }); return; } if (!bankCard.documentPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei von Festplatte löschen const filePath = path_1.default.join(process.cwd(), bankCard.documentPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // documentPath in DB auf null setzen await prisma.bankCard.update({ where: { id: bankCardId }, data: { documentPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); // Löschen von Ausweis-Dokumenten router.delete('/documents/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), async (req, res) => { try { const documentId = parseInt(req.params.id); // Ausweis aus DB holen um Dateipfad zu bekommen const document = await prisma.identityDocument.findUnique({ where: { id: documentId }, }); if (!document) { res.status(404).json({ success: false, error: 'Ausweis nicht gefunden' }); return; } if (!document.documentPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei von Festplatte löschen const filePath = path_1.default.join(process.cwd(), document.documentPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // documentPath in DB auf null setzen await prisma.identityDocument.update({ where: { id: documentId }, data: { documentPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); // ==================== FIRMEN-DOKUMENTE ==================== // Upload für Gewerbeanmeldung router.post('/customers/:id/business-registration', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), setUploadDir('business-registrations'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const customerId = parseInt(req.params.id); const relativePath = `/uploads/business-registrations/${req.file.filename}`; // Alte Datei löschen falls vorhanden const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (customer?.businessRegistrationPath) { const oldPath = path_1.default.join(process.cwd(), customer.businessRegistrationPath); if (fs_1.default.existsSync(oldPath)) { fs_1.default.unlinkSync(oldPath); } } // Kunde in der DB aktualisieren await prisma.customer.update({ where: { id: customerId }, data: { businessRegistrationPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Upload für Handelsregisterauszug router.post('/customers/:id/commercial-register', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), setUploadDir('commercial-registers'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const customerId = parseInt(req.params.id); const relativePath = `/uploads/commercial-registers/${req.file.filename}`; // Alte Datei löschen falls vorhanden const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (customer?.commercialRegisterPath) { const oldPath = path_1.default.join(process.cwd(), customer.commercialRegisterPath); if (fs_1.default.existsSync(oldPath)) { fs_1.default.unlinkSync(oldPath); } } // Kunde in der DB aktualisieren await prisma.customer.update({ where: { id: customerId }, data: { commercialRegisterPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Löschen der Gewerbeanmeldung router.delete('/customers/:id/business-registration', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), async (req, res) => { try { const customerId = parseInt(req.params.id); const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (!customer) { res.status(404).json({ success: false, error: 'Kunde nicht gefunden' }); return; } if (!customer.businessRegistrationPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei löschen const filePath = path_1.default.join(process.cwd(), customer.businessRegistrationPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // Pfad in DB auf null setzen await prisma.customer.update({ where: { id: customerId }, data: { businessRegistrationPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); // Löschen des Handelsregisterauszugs router.delete('/customers/:id/commercial-register', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), async (req, res) => { try { const customerId = parseInt(req.params.id); const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (!customer) { res.status(404).json({ success: false, error: 'Kunde nicht gefunden' }); return; } if (!customer.commercialRegisterPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei löschen const filePath = path_1.default.join(process.cwd(), customer.commercialRegisterPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // Pfad in DB auf null setzen await prisma.customer.update({ where: { id: customerId }, data: { commercialRegisterPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); // ==================== DATENSCHUTZERKLÄRUNG (für alle Kunden) ==================== // Upload für Datenschutzerklärung router.post('/customers/:id/privacy-policy', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), setUploadDir('privacy-policies'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const customerId = parseInt(req.params.id); const relativePath = `/uploads/privacy-policies/${req.file.filename}`; // Alte Datei löschen falls vorhanden const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (customer?.privacyPolicyPath) { const oldPath = path_1.default.join(process.cwd(), customer.privacyPolicyPath); if (fs_1.default.existsSync(oldPath)) { fs_1.default.unlinkSync(oldPath); } } // Kunde in der DB aktualisieren await prisma.customer.update({ where: { id: customerId }, data: { privacyPolicyPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Löschen der Datenschutzerklärung router.delete('/customers/:id/privacy-policy', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('customers:update'), async (req, res) => { try { const customerId = parseInt(req.params.id); const customer = await prisma.customer.findUnique({ where: { id: customerId } }); if (!customer) { res.status(404).json({ success: false, error: 'Kunde nicht gefunden' }); return; } if (!customer.privacyPolicyPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei löschen const filePath = path_1.default.join(process.cwd(), customer.privacyPolicyPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // Pfad in DB auf null setzen await prisma.customer.update({ where: { id: customerId }, data: { privacyPolicyPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); // ==================== VERTRAGS-DOKUMENTE ==================== // Generische Funktion für Vertrags-Dokument Upload async function handleContractDocumentUpload(req, res, fieldName, subDir) { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const contractId = parseInt(req.params.id); const relativePath = `/uploads/${subDir}/${req.file.filename}`; // Alte Datei löschen falls vorhanden const contract = await prisma.contract.findUnique({ where: { id: contractId } }); if (!contract) { res.status(404).json({ success: false, error: 'Vertrag nicht gefunden' }); return; } const oldPath = contract[fieldName]; if (oldPath) { const fullPath = path_1.default.join(process.cwd(), oldPath); if (fs_1.default.existsSync(fullPath)) { fs_1.default.unlinkSync(fullPath); } } // Vertrag in der DB aktualisieren await prisma.contract.update({ where: { id: contractId }, data: { [fieldName]: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } } // Generische Funktion für Vertrags-Dokument Löschen async function handleContractDocumentDelete(req, res, fieldName) { try { const contractId = parseInt(req.params.id); const contract = await prisma.contract.findUnique({ where: { id: contractId } }); if (!contract) { res.status(404).json({ success: false, error: 'Vertrag nicht gefunden' }); return; } const documentPath = contract[fieldName]; if (!documentPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei löschen const filePath = path_1.default.join(process.cwd(), documentPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // Pfad in DB auf null setzen await prisma.contract.update({ where: { id: contractId }, data: { [fieldName]: null }, }); res.json({ success: true }); } catch (error) { console.error('Delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } } // Kündigungsschreiben router.post('/contracts/:id/cancellation-letter', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), setUploadDir('cancellation-letters'), upload.single('document'), (req, res) => handleContractDocumentUpload(req, res, 'cancellationLetterPath', 'cancellation-letters')); router.delete('/contracts/:id/cancellation-letter', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), (req, res) => handleContractDocumentDelete(req, res, 'cancellationLetterPath')); // Kündigungsbestätigung router.post('/contracts/:id/cancellation-confirmation', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), setUploadDir('cancellation-confirmations'), upload.single('document'), (req, res) => handleContractDocumentUpload(req, res, 'cancellationConfirmationPath', 'cancellation-confirmations')); router.delete('/contracts/:id/cancellation-confirmation', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), (req, res) => handleContractDocumentDelete(req, res, 'cancellationConfirmationPath')); // Kündigungsschreiben Optionen router.post('/contracts/:id/cancellation-letter-options', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), setUploadDir('cancellation-letters-options'), upload.single('document'), (req, res) => handleContractDocumentUpload(req, res, 'cancellationLetterOptionsPath', 'cancellation-letters-options')); router.delete('/contracts/:id/cancellation-letter-options', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), (req, res) => handleContractDocumentDelete(req, res, 'cancellationLetterOptionsPath')); // Kündigungsbestätigung Optionen router.post('/contracts/:id/cancellation-confirmation-options', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), setUploadDir('cancellation-confirmations-options'), upload.single('document'), (req, res) => handleContractDocumentUpload(req, res, 'cancellationConfirmationOptionsPath', 'cancellation-confirmations-options')); router.delete('/contracts/:id/cancellation-confirmation-options', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), (req, res) => handleContractDocumentDelete(req, res, 'cancellationConfirmationOptionsPath')); // ==================== RECHNUNGS-DOKUMENTE ==================== // Upload für Rechnungs-Dokument router.post('/invoices/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), setUploadDir('invoices'), upload.single('document'), async (req, res) => { try { if (!req.file) { res.status(400).json({ success: false, error: 'Keine Datei hochgeladen' }); return; } const invoiceId = parseInt(req.params.id); const relativePath = `/uploads/invoices/${req.file.filename}`; // Alte Datei löschen falls vorhanden const invoice = await prisma.invoice.findUnique({ where: { id: invoiceId } }); if (!invoice) { res.status(404).json({ success: false, error: 'Rechnung nicht gefunden' }); return; } if (invoice.documentPath) { const oldPath = path_1.default.join(process.cwd(), invoice.documentPath); if (fs_1.default.existsSync(oldPath)) { fs_1.default.unlinkSync(oldPath); } } // Invoice in der DB aktualisieren await prisma.invoice.update({ where: { id: invoiceId }, data: { documentPath: relativePath }, }); res.json({ success: true, data: { path: relativePath, filename: req.file.filename, originalName: req.file.originalname, size: req.file.size, }, }); } catch (error) { console.error('Invoice upload error:', error); res.status(500).json({ success: false, error: 'Upload fehlgeschlagen' }); } }); // Löschen von Rechnungs-Dokument router.delete('/invoices/:id', auth_js_1.authenticate, (0, auth_js_1.requirePermission)('contracts:update'), async (req, res) => { try { const invoiceId = parseInt(req.params.id); const invoice = await prisma.invoice.findUnique({ where: { id: invoiceId } }); if (!invoice) { res.status(404).json({ success: false, error: 'Rechnung nicht gefunden' }); return; } if (!invoice.documentPath) { res.status(400).json({ success: false, error: 'Kein Dokument vorhanden' }); return; } // Datei löschen const filePath = path_1.default.join(process.cwd(), invoice.documentPath); if (fs_1.default.existsSync(filePath)) { fs_1.default.unlinkSync(filePath); } // documentPath in DB auf null setzen await prisma.invoice.update({ where: { id: invoiceId }, data: { documentPath: null }, }); res.json({ success: true }); } catch (error) { console.error('Invoice delete error:', error); res.status(500).json({ success: false, error: 'Löschen fehlgeschlagen' }); } }); exports.default = router; //# sourceMappingURL=upload.routes.js.map