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
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { z } from 'zod';
|
||||
import { DistanceCalculator } from '@/lib/distance-calculator';
|
||||
import { PriceCalculator } from '@/lib/price-calculator';
|
||||
import { bookingAutomationService } from '@/lib/booking-automation';
|
||||
|
||||
const bookingSchema = z.object({
|
||||
locationSlug: z.string(),
|
||||
@@ -92,7 +95,62 @@ export async function POST(request: NextRequest) {
|
||||
},
|
||||
});
|
||||
|
||||
const calculatedPrice = priceConfig ? priceConfig.basePrice : 0;
|
||||
if (!priceConfig) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Preiskonfiguration nicht gefunden' },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
let distance: number | null = null;
|
||||
let calculatedPrice = priceConfig.basePrice;
|
||||
|
||||
if (location.warehouseAddress && location.warehouseZip && location.warehouseCity) {
|
||||
const warehouseAddress = DistanceCalculator.formatAddress(
|
||||
location.warehouseAddress,
|
||||
location.warehouseZip,
|
||||
location.warehouseCity
|
||||
);
|
||||
const eventAddress = DistanceCalculator.formatAddress(
|
||||
data.eventAddress,
|
||||
data.eventZip,
|
||||
data.eventCity
|
||||
);
|
||||
|
||||
const distanceResult = await DistanceCalculator.calculateDistance(
|
||||
warehouseAddress,
|
||||
eventAddress
|
||||
);
|
||||
|
||||
if (distanceResult) {
|
||||
distance = distanceResult.distance;
|
||||
|
||||
const priceBreakdown = PriceCalculator.calculateTotalPrice(
|
||||
priceConfig.basePrice,
|
||||
distance,
|
||||
{
|
||||
basePrice: priceConfig.basePrice,
|
||||
kmFlatRate: priceConfig.kmFlatRate,
|
||||
kmFlatRateUpTo: priceConfig.kmFlatRateUpTo,
|
||||
pricePerKm: priceConfig.pricePerKm,
|
||||
kmMultiplier: priceConfig.kmMultiplier,
|
||||
}
|
||||
);
|
||||
|
||||
calculatedPrice = priceBreakdown.totalPrice;
|
||||
|
||||
console.log('📍 Distanzberechnung:', {
|
||||
from: warehouseAddress,
|
||||
to: eventAddress,
|
||||
distance: `${distance}km`,
|
||||
breakdown: PriceCalculator.formatPriceBreakdown(priceBreakdown),
|
||||
});
|
||||
} else {
|
||||
console.warn('⚠️ Distanzberechnung fehlgeschlagen, verwende nur Grundpreis');
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ Keine Lager-Adresse konfiguriert, verwende nur Grundpreis');
|
||||
}
|
||||
|
||||
const booking = await prisma.booking.create({
|
||||
data: {
|
||||
@@ -117,6 +175,7 @@ export async function POST(request: NextRequest) {
|
||||
setupTimeLatest: new Date(data.setupTimeLatest),
|
||||
dismantleTimeEarliest: data.dismantleTimeEarliest ? new Date(data.dismantleTimeEarliest) : null,
|
||||
dismantleTimeLatest: data.dismantleTimeLatest ? new Date(data.dismantleTimeLatest) : null,
|
||||
distance,
|
||||
calculatedPrice,
|
||||
notes: data.notes,
|
||||
},
|
||||
@@ -138,6 +197,12 @@ export async function POST(request: NextRequest) {
|
||||
},
|
||||
});
|
||||
|
||||
// 🤖 Automatische Post-Booking Aktionen (E-Mail + Kalender)
|
||||
console.log('📢 Starte automatische Aktionen...');
|
||||
bookingAutomationService.runPostBookingActions(booking.id).catch(err => {
|
||||
console.error('⚠️ Automatische Aktionen fehlgeschlagen:', err);
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
booking: {
|
||||
@@ -174,7 +239,13 @@ export async function GET(request: NextRequest) {
|
||||
const where: any = {};
|
||||
|
||||
if (status) {
|
||||
where.status = status;
|
||||
// Support multiple statuses separated by comma
|
||||
const statuses = status.split(',').map(s => s.trim());
|
||||
if (statuses.length > 1) {
|
||||
where.status = { in: statuses };
|
||||
} else {
|
||||
where.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
if (locationSlug) {
|
||||
|
||||
Reference in New Issue
Block a user