import { Request, Response } from 'express'; import * as invoiceService from '../services/invoice.service.js'; import { logChange } from '../services/audit.service.js'; import { ApiResponse, AuthRequest } from '../types/index.js'; import { canAccessContract, canAccessEnergyContractDetails } from '../utils/accessControl.js'; /** * Alle Rechnungen für ein EnergyContractDetails abrufen */ export async function getInvoices(req: AuthRequest, res: Response): Promise { try { const ecdId = parseInt(req.params.ecdId); if (!(await canAccessEnergyContractDetails(req, res, ecdId))) return; const invoices = await invoiceService.getInvoices(ecdId); res.json({ success: true, data: invoices } as ApiResponse); } catch (error) { console.error('getInvoices error:', error); res.status(500).json({ success: false, error: 'Fehler beim Laden der Rechnungen', } as ApiResponse); } } /** * Einzelne Rechnung abrufen */ export async function getInvoice(req: AuthRequest, res: Response): Promise { try { const ecdId = parseInt(req.params.ecdId); const invoiceId = parseInt(req.params.invoiceId); if (!(await canAccessEnergyContractDetails(req, res, ecdId))) return; const invoice = await invoiceService.getInvoice(ecdId, invoiceId); if (!invoice) { res.status(404).json({ success: false, error: 'Rechnung nicht gefunden', } as ApiResponse); return; } res.json({ success: true, data: invoice } as ApiResponse); } catch (error) { console.error('getInvoice error:', error); res.status(500).json({ success: false, error: 'Fehler beim Laden der Rechnung', } as ApiResponse); } } /** * Neue Rechnung hinzufügen */ export async function addInvoice(req: AuthRequest, res: Response): Promise { try { const ecdId = parseInt(req.params.ecdId); if (!(await canAccessEnergyContractDetails(req, res, ecdId))) return; const { invoiceDate, invoiceType, documentPath, notes } = req.body; if (!invoiceDate || !invoiceType) { res.status(400).json({ success: false, error: 'invoiceDate und invoiceType sind erforderlich', } as ApiResponse); return; } const invoice = await invoiceService.addInvoice(ecdId, { invoiceDate: new Date(invoiceDate), invoiceType, documentPath, notes, }); await logChange({ req, action: 'CREATE', resourceType: 'Invoice', resourceId: invoice.id.toString(), label: `Rechnung (${invoiceType}) hinzugefügt`, }); res.status(201).json({ success: true, data: invoice } as ApiResponse); } catch (error) { console.error('addInvoice error:', error); res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Hinzufügen der Rechnung', } as ApiResponse); } } /** * Rechnung aktualisieren */ export async function updateInvoice(req: AuthRequest, res: Response): Promise { try { const ecdId = parseInt(req.params.ecdId); const invoiceId = parseInt(req.params.invoiceId); if (!(await canAccessEnergyContractDetails(req, res, ecdId))) return; const { invoiceDate, invoiceType, documentPath, notes } = req.body; const invoice = await invoiceService.updateInvoice(ecdId, invoiceId, { invoiceDate: invoiceDate ? new Date(invoiceDate) : undefined, invoiceType, documentPath, notes, }); await logChange({ req, action: 'UPDATE', resourceType: 'Invoice', resourceId: invoiceId.toString(), label: `Rechnung aktualisiert`, }); res.json({ success: true, data: invoice } as ApiResponse); } catch (error) { console.error('updateInvoice error:', error); res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Aktualisieren der Rechnung', } as ApiResponse); } } /** * Rechnung löschen */ export async function deleteInvoice(req: AuthRequest, res: Response): Promise { try { const ecdId = parseInt(req.params.ecdId); const invoiceId = parseInt(req.params.invoiceId); if (!(await canAccessEnergyContractDetails(req, res, ecdId))) return; await invoiceService.deleteInvoice(ecdId, invoiceId); await logChange({ req, action: 'DELETE', resourceType: 'Invoice', resourceId: invoiceId.toString(), label: `Rechnung gelöscht`, }); res.json({ success: true, data: null } as ApiResponse); } catch (error) { console.error('deleteInvoice error:', error); res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Löschen der Rechnung', } as ApiResponse); } } // ==================== CONTRACT-BASIERTE RECHNUNGEN (für alle Vertragstypen) ==================== export async function getInvoicesByContract(req: AuthRequest, res: Response): Promise { try { const contractId = parseInt(req.params.id); if (!(await canAccessContract(req, res, contractId))) return; const invoices = await invoiceService.getInvoicesByContract(contractId); res.json({ success: true, data: invoices } as ApiResponse); } catch (error) { res.status(500).json({ success: false, error: 'Fehler beim Laden der Rechnungen' } as ApiResponse); } } export async function addInvoiceByContract(req: AuthRequest, res: Response): Promise { try { const contractId = parseInt(req.params.id); if (!(await canAccessContract(req, res, contractId))) return; const { invoiceDate, invoiceType, notes } = req.body; const invoice = await invoiceService.addInvoiceByContract(contractId, { invoiceDate: new Date(invoiceDate), invoiceType, notes, }); await logChange({ req, action: 'CREATE', resourceType: 'Invoice', resourceId: invoice.id.toString(), label: `Rechnung (${invoiceType}) hinzugefügt`, }); res.status(201).json({ success: true, data: invoice } as ApiResponse); } catch (error) { res.status(400).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Hinzufügen', } as ApiResponse); } }