Files
Atlas/app/api/bookings/create/route.ts
2025-11-12 20:21:32 +01:00

126 lines
3.7 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';
import { nextcloudCalendar } from '@/lib/nextcloud-calendar';
function generateBookingNumber(): string {
const date = new Date();
const year = date.getFullYear().toString().slice(-2);
const month = String(date.getMonth() + 1).padStart(2, '0');
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return `STM-${year}${month}-${random}`;
}
export async function POST(request: NextRequest) {
try {
const session = await getServerSession(authOptions);
if (!session || session.user.role !== 'ADMIN') {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const eventDate = new Date(body.eventDate);
const startOfDay = new Date(eventDate);
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(eventDate);
endOfDay.setHours(23, 59, 59, 999);
const availablePhotobox = await prisma.photobox.findFirst({
where: {
locationId: body.locationId,
model: body.model,
active: true,
NOT: {
bookings: {
some: {
eventDate: {
gte: startOfDay,
lte: endOfDay,
},
status: {
in: ['RESERVED', 'CONFIRMED'],
},
},
},
},
},
});
if (!availablePhotobox) {
return NextResponse.json(
{ error: 'Keine Fotobox verfügbar für dieses Datum' },
{ status: 409 }
);
}
const booking = await prisma.booking.create({
data: {
bookingNumber: generateBookingNumber(),
locationId: body.locationId,
photoboxId: availablePhotobox.id,
status: 'RESERVED',
customerName: body.customerName,
customerEmail: body.customerEmail,
customerPhone: body.customerPhone,
customerAddress: body.customerAddress,
customerCity: body.customerCity,
customerZip: body.customerZip,
invoiceType: body.invoiceType,
companyName: body.companyName,
eventDate: new Date(body.eventDate),
eventAddress: body.eventAddress,
eventCity: body.eventCity,
eventZip: body.eventZip,
eventLocation: body.eventLocation,
setupTimeStart: new Date(body.setupTimeStart),
setupTimeLatest: new Date(body.setupTimeLatest),
dismantleTimeEarliest: body.dismantleTimeEarliest ? new Date(body.dismantleTimeEarliest) : null,
dismantleTimeLatest: body.dismantleTimeLatest ? new Date(body.dismantleTimeLatest) : null,
calculatedPrice: body.calculatedPrice,
notes: body.notes,
},
include: {
location: true,
photobox: true,
},
});
await prisma.notification.create({
data: {
type: 'NEW_BOOKING_MANUAL',
title: 'Neue manuelle Buchung',
message: `${body.customerName} - ${eventDate.toLocaleDateString('de-DE')}`,
metadata: {
bookingId: booking.id,
bookingNumber: booking.bookingNumber,
},
},
});
try {
await nextcloudCalendar.syncBookingToCalendar(booking);
} catch (calError) {
console.error('Calendar sync error after booking creation:', calError);
}
return NextResponse.json({
success: true,
booking,
});
} catch (error: any) {
console.error('Booking creation error:', error);
return NextResponse.json(
{ error: error.message || 'Internal server error' },
{ status: 500 }
);
}
}