189 lines
6.1 KiB
TypeScript
189 lines
6.1 KiB
TypeScript
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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);
|
|
}
|
|
}
|