Files
Atlas/app/api/bookings/[id]/sign/route.ts
Julia Wehden a2c95c70e7 feat: Equipment-System, Buchungsbearbeitung, Kundenadresse, LexOffice-Fix
- Vintage Modell hinzugefuegt
- Equipment Multi-Select (Neue Buchung + Bearbeitung)
- Kundenadresse in Formularen
- Bearbeiten-Seite fuer Buchungen
- Abbau-Zeiten in Formularen und Uebersicht
- Vertrag PDF nur bei Privatkunden
- LexOffice Kontakt-Erstellung Fix (BUSINESS)
- Zurueck-Pfeil auf Touren-Seite
2026-03-19 16:21:55 +01:00

166 lines
4.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { generateContractFromTemplate } from '@/lib/pdf-template-service';
export async function POST(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const bookingId = params.id;
const body = await request.json();
const { signatureData } = body;
if (!signatureData) {
return NextResponse.json(
{ error: 'Signatur-Daten fehlen' },
{ status: 400 }
);
}
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
include: {
location: true,
photobox: true,
},
});
if (!booking) {
return NextResponse.json(
{ error: 'Buchung nicht gefunden' },
{ status: 404 }
);
}
if (booking.contractSigned) {
return NextResponse.json(
{ error: 'Vertrag wurde bereits unterschrieben' },
{ status: 400 }
);
}
const clientIp = request.headers.get('x-forwarded-for') ||
request.headers.get('x-real-ip') ||
'unknown';
let priceConfig = null;
if (booking.photobox?.model && booking.locationId) {
priceConfig = await prisma.priceConfig.findUnique({
where: {
locationId_model: {
locationId: booking.locationId,
model: booking.photobox.model,
},
},
});
}
const bookingWithPriceConfig = {
...booking,
priceConfig,
};
const contractPdf = await generateContractFromTemplate(
bookingWithPriceConfig,
booking.location,
booking.photobox,
signatureData
);
const updatedBooking = await prisma.booking.update({
where: { id: bookingId },
data: {
contractSigned: true,
contractSignedAt: new Date(),
contractSignedOnline: true,
contractSignatureData: signatureData,
contractSignedBy: booking.customerName,
contractSignedIp: clientIp,
},
});
await prisma.notification.create({
data: {
type: 'CONTRACT_SIGNED',
title: 'Vertrag unterschrieben',
message: `${booking.customerName} hat den Vertrag für Buchung ${booking.bookingNumber} online unterschrieben.`,
metadata: {
bookingId: booking.id,
bookingNumber: booking.bookingNumber,
signedOnline: true,
},
},
});
console.log(`✅ Vertrag online unterschrieben: ${booking.bookingNumber}`);
return NextResponse.json({
success: true,
booking: {
id: updatedBooking.id,
bookingNumber: updatedBooking.bookingNumber,
contractSigned: updatedBooking.contractSigned,
contractSignedAt: updatedBooking.contractSignedAt,
},
});
} catch (error: any) {
console.error('❌ Signatur-Fehler:', error);
return NextResponse.json(
{ error: error.message || 'Signatur fehlgeschlagen' },
{ status: 500 }
);
}
}
export async function GET(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const bookingId = params.id;
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
select: {
id: true,
bookingNumber: true,
customerName: true,
eventDate: true,
eventLocation: true,
contractSigned: true,
contractSignedAt: true,
contractSignedOnline: true,
calculatedPrice: true,
photobox: {
select: {
model: true,
},
},
location: {
select: {
name: true,
},
},
},
});
if (!booking) {
return NextResponse.json(
{ error: 'Buchung nicht gefunden' },
{ status: 404 }
);
}
return NextResponse.json({ booking });
} catch (error: any) {
console.error('❌ Buchungs-Abruf Fehler:', error);
return NextResponse.json(
{ error: error.message || 'Fehler beim Abrufen der Buchung' },
{ status: 500 }
);
}
}