Nichtbetrachten und Daten zusammen

This commit is contained in:
2026-08-16 07:55:51 +00:00
parent 550da31038
commit 90a7d8d3d2
10 changed files with 2415 additions and 489 deletions

View File

@@ -1,90 +1,79 @@
import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
function parseGermanPrice(priceStr: any): number | null {
if (!priceStr) return null;
if (typeof priceStr === 'number') return Math.round(priceStr);
let cleaned = String(priceStr).replace(/[^0-9.,]/g, '').trim();
if (!cleaned) return null;
if (cleaned.includes('.') && !cleaned.includes(',')) {
cleaned = cleaned.replace(/\./g, '');
} else if (cleaned.includes('.') && cleaned.includes(',')) {
cleaned = cleaned.replace(/\./g, '').replace(',', '.');
} else if (cleaned.includes(',')) {
cleaned = cleaned.replace(',', '.');
}
const parsed = parseFloat(cleaned);
return isNaN(parsed) ? null : Math.round(parsed);
}
export async function POST(req: NextRequest) {
try {
const body = await req.json().catch(() => ({}));
const { searchParams } = new URL(req.url);
const hotelId = searchParams.get('hotelId');
const body = await req.json();
const {
price,
roomSizeM2,
hotelName,
rating,
reviewCount,
address,
image,
nights = 1,
persons = 2,
} = body;
const hotelId = searchParams.get('hotelId') || body.hotelId;
if (!hotelId) {
return NextResponse.json({ error: 'hotelId fehlt' }, { status: 400 });
return NextResponse.json({ success: false, error: 'hotelId fehlt' }, { status: 400 });
}
const parseNum = (val: any): number | null => {
if (typeof val === 'number') return val;
if (!val || typeof val !== 'string') return null;
const match = val.replace(',', '.').match(/\d+(\.\d+)?/);
return match ? parseFloat(match[0]) : null;
};
const numericPrice = parseGermanPrice(body.price);
const numPrice = parseNum(price);
// Automatisch 10 % Genius Rabatt berechnen
let numGenius: number | null = null;
if (numPrice !== null) {
numGenius = parseFloat((numPrice * 0.90).toFixed(2));
// 1. In hotel_price_history eintragen mit echten Spalten
if (numericPrice !== null && numericPrice > 0) {
try {
await query(
`INSERT INTO hotel_price_history (hotel_id, price_numeric, price_raw, currency, nights, persons, tracked_at)
VALUES ($1::uuid, $2, $3, 'EUR', $4, $5, NOW())`,
[hotelId, numericPrice, String(body.price || ''), body.nights || 1, body.persons || 2]
);
} catch (err: any) {
console.error('DB Insert Error (hotel_price_history):', err.message);
}
}
// Ratenberechnung auf Basis des Genius-Preises
const basePrice = numGenius || numPrice;
let pricePerNight = null;
let pricePerPersonPerNight = null;
if (basePrice !== null && nights > 0 && persons > 0) {
// 1. Zimmerpreis pro Nacht
pricePerNight = parseFloat((basePrice / nights).toFixed(2));
// 2. Preis pro Person & Nacht
pricePerPersonPerNight = parseFloat((basePrice / (nights * persons)).toFixed(2));
}
// 1. In Preishistorie eintragen
if (numPrice !== null) {
// 2. Stammdaten aktualisieren
try {
await query(
`INSERT INTO hotel_price_history
(hotel_id, price_numeric, genius_price_numeric, price_raw, price_per_night, price_per_person, nights, persons)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
`UPDATE hotels
SET name = COALESCE($1, name),
rating = COALESCE($2, rating),
review_count = COALESCE($3, review_count),
address = COALESCE($4, address),
image_url = COALESCE($5, image_url),
room_size_m2 = COALESCE($6, room_size_m2),
updated_at = NOW()
WHERE id = $7::uuid`,
[
hotelId,
numPrice,
numGenius,
price ? String(price) : null,
pricePerNight,
pricePerPersonPerNight,
nights,
persons,
body.hotelName || null,
body.rating || null,
body.reviewCount || null,
body.address || null,
body.image || null,
body.roomSizeM2 || null,
hotelId
]
);
} catch (err: any) {
console.error('DB Update Error (hotels):', err.message);
}
// 2. Hotel Stammdaten aktualisieren
await query(
`UPDATE hotels
SET name = COALESCE($1, name),
rating = COALESCE($2, rating),
review_count = COALESCE($3, review_count),
address = COALESCE($4, address),
image_url = COALESCE($5, image_url),
room_size_m2 = COALESCE($6, room_size_m2)
WHERE id = $7`,
[hotelName, rating, reviewCount, address, image, roomSizeM2, hotelId]
);
return NextResponse.json({ success: true });
return NextResponse.json({ success: true, hotelId, parsedPrice: numericPrice });
} catch (error: any) {
console.error('Webhook Error:', error);
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
console.error('Allgemeiner Fehler im Webhook:', error.message);
return NextResponse.json({ success: false, error: error.message }, { status: 200 });
}
}