84 lines
3.4 KiB
TypeScript
84 lines
3.4 KiB
TypeScript
// /opt/erp-system/app/api/customers/route.ts
|
|
import { NextResponse } from 'next/server';
|
|
import prisma from '../../../lib/prisma';
|
|
import bcrypt from 'bcryptjs';
|
|
import { sendEmail } from '../../../lib/email';
|
|
import { getServerSession } from "next-auth/next";
|
|
import { authOptions } from "../auth/[...nextauth]/route";
|
|
|
|
export async function GET() {
|
|
const session = await getServerSession(authOptions);
|
|
if (!session) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });
|
|
|
|
const customers = await prisma.customer.findMany({ orderBy: { companyName: 'asc' } });
|
|
return NextResponse.json(customers);
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
const session = await getServerSession(authOptions);
|
|
if (!session) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });
|
|
|
|
try {
|
|
const body = await request.json();
|
|
|
|
// 1. Zufälliges Start-Passwort generieren (8 Zeichen)
|
|
const tempPassword = Math.random().toString(36).slice(-8);
|
|
const hash = await bcrypt.hash(tempPassword, 10);
|
|
|
|
// 2. Kunde anlegen
|
|
const customer = await prisma.customer.create({
|
|
data: {
|
|
companyName: body.companyName,
|
|
firstName: body.firstName,
|
|
lastName: body.lastName,
|
|
email: body.email,
|
|
phone: body.phone,
|
|
passwordHash: hash,
|
|
forcePasswordChange: true // Muss beim ersten Login geändert werden
|
|
}
|
|
});
|
|
|
|
// 3. Willkommens-E-Mail senden
|
|
await sendEmail({
|
|
to: customer.email,
|
|
subject: "Willkommen im Kundenportal",
|
|
text: `Hallo ${customer.firstName} ${customer.lastName},\n\nIhr Kundenkonto wurde erfolgreich eingerichtet.\n\nIhre Zugangsdaten lauten:\nLogin: ${customer.email}\nPasswort: ${tempPassword}\n\nBitte loggen Sie sich in unser Portal ein. Sie werden nach dem ersten Login aufgefordert, ein eigenes Passwort zu vergeben.\n\nViele Grüße\nIhr Support-Team`
|
|
});
|
|
|
|
return NextResponse.json(customer, { status: 201 });
|
|
} catch (error: any) {
|
|
console.error(error);
|
|
return NextResponse.json({ error: 'Fehler beim Erstellen des Kunden' }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function DELETE(request: Request) {
|
|
const session = await getServerSession(authOptions);
|
|
const perms = (session?.user as any)?.permissions || [];
|
|
if (!perms.includes('DATA_DELETE')) return NextResponse.json({ error: 'Keine Löschberechtigung' }, { status: 403 });
|
|
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const id = searchParams.get('id');
|
|
if (!id) return NextResponse.json({ error: 'ID fehlt' }, { status: 400 });
|
|
|
|
const customerId = parseInt(id);
|
|
|
|
// Delete all related data first (non-cascading relations)
|
|
await prisma.ticketMessage.deleteMany({ where: { ticket: { customerId } } });
|
|
await prisma.ticketNote.deleteMany({ where: { ticket: { customerId } } });
|
|
await prisma.timeEntry.deleteMany({ where: { ticket: { customerId } } });
|
|
await prisma.ticketSurvey.deleteMany({ where: { ticket: { customerId } } });
|
|
await prisma.attachment.deleteMany({ where: { ticket: { customerId } } });
|
|
await prisma.ticket.deleteMany({ where: { customerId } });
|
|
|
|
// Cascading relations (contacts, contracts, documents, credentials) are handled by onDelete: Cascade
|
|
await prisma.customer.delete({ where: { id: customerId } });
|
|
|
|
return NextResponse.json({ success: true });
|
|
} catch (error) {
|
|
console.error(error);
|
|
return NextResponse.json({ error: 'Löschen fehlgeschlagen' }, { status: 500 });
|
|
}
|
|
}
|