import { NextResponse } from 'next/server'; import prisma from '../../../lib/prisma'; import { getServerSession } from "next-auth/next"; import { authOptions } from "../auth/[...nextauth]/route"; async function getSession() { const session = await getServerSession(authOptions); if (!session) return null; return session; } const PREFIXES: Record = { QUOTE: 'ANG', ORDER_CONFIRMATION: 'AB', DELIVERY_NOTE: 'LS', INVOICE: 'RE', CREDIT_NOTE: 'RK' }; const NUMBER_FIELDS: Record = { QUOTE: 'nextQuoteNumber', ORDER_CONFIRMATION: 'nextOrderNumber', DELIVERY_NOTE: 'nextDeliveryNumber', INVOICE: 'nextInvoiceNumber', CREDIT_NOTE: 'nextCreditNoteNumber' }; async function generateNumber(type: string) { const settings = await prisma.systemSettings.findFirst(); if (!settings) throw new Error('SystemSettings not found'); const year = new Date().getFullYear(); const prefix = PREFIXES[type] || 'DOC'; const field = NUMBER_FIELDS[type]; const num = (settings as any)[field] || 1; await prisma.systemSettings.update({ where: { id: settings.id }, data: { [field]: num + 1 } }); return `${prefix}-${year}-${num.toString().padStart(4, '0')}`; } export async function GET(request: Request) { const session = await getSession(); if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); try { const { searchParams } = new URL(request.url); const customerId = searchParams.get('customerId'); const where = customerId ? { customerId: parseInt(customerId) } : {}; const docs = await prisma.salesDocument.findMany({ where, include: { customer: { select: { companyName: true, firstName: true, lastName: true } }, items: { include: { product: { select: { name: true } } } }, createdBy: { select: { firstName: true, lastName: true } } }, orderBy: { createdAt: 'desc' } }); return NextResponse.json(docs); } catch (error) { console.error(error); return NextResponse.json({ error: 'Ladefehler' }, { status: 500 }); } } export async function POST(request: Request) { const session = await getSession(); const perms = (session?.user as any)?.permissions || []; if (!perms.includes('SALES_MANAGE')) return NextResponse.json({ error: 'Keine Berechtigung' }, { status: 403 }); try { const body = await request.json(); const number = await generateNumber(body.type); // Auto-set validity for quotes let validUntil = body.validUntil ? new Date(body.validUntil) : null; if (body.type === 'QUOTE' && !validUntil) { const settings = await prisma.systemSettings.findFirst(); if (settings?.defaultQuoteValidityDays) { validUntil = new Date(); validUntil.setDate(validUntil.getDate() + settings.defaultQuoteValidityDays); } } // Calculate totals let subtotal = 0; const items = (body.items || []).map((item: any) => { const total = item.quantity * item.unitPrice; subtotal += total; return { ...item, total, taxRate: 19 }; }); const taxAmount = subtotal * 0.19; const total = subtotal + taxAmount; const doc = await prisma.salesDocument.create({ data: { type: body.type, number, customerId: body.customerId, createdById: (session?.user as any)?.id || null, notes: body.notes || null, validUntil, subtotal, taxAmount, total, items: { create: items.map((i: any) => ({ description: i.description, quantity: i.quantity, unitPrice: i.unitPrice, taxRate: i.taxRate, total: i.total, productId: i.productId || null })) } }, include: { items: true, customer: true } }); return NextResponse.json(doc, { status: 201 }); } catch (error) { console.error(error); return NextResponse.json({ error: 'Fehler beim Erstellen' }, { status: 500 }); } }