Implement order data model modernization and license transformation logic

This commit is contained in:
DanielS
2026-05-03 20:13:36 +02:00
parent f947798bf6
commit 5c393ecb57
7 changed files with 422 additions and 132 deletions

View File

@@ -5,89 +5,74 @@ import { revalidatePath } from 'next/cache'
import { InvoicePDF } from '@/components/invoice-pdf'
import { renderToBuffer } from '@react-pdf/renderer'
import React from 'react'
import { buildCustomerSnapshot, buildOrderSnapshot } from '@/lib/license-transform'
import type { Category, Order, Product, Profile, WizardSelections } from '@/lib/types'
export async function submitOrder(orderData: {
product_id: string;
selected_modules: string[];
total_amount: number;
customer_details: any;
}) {
// ─── submitOrder ──────────────────────────────────────────────────────────────
/**
* Speichert eine abgeschlossene Bestellung als versionierten Snapshot in der DB,
* generiert die PDF-Rechnung und lädt sie in den Supabase Storage hoch.
*/
export async function submitOrder(params: {
selections: WizardSelections
products: Product[]
categories: Category[]
customerProfile: Partial<Profile>
}): Promise<Order> {
const { selections, products, categories, customerProfile } = params
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) throw new Error('Not authenticated')
// 1. Fetch Product and Module Details for Invoice
const { data: product } = await supabase
.from('products')
.select('*')
.eq('id', orderData.product_id)
.single()
// 1. Snapshots aufbauen
const customerSnapshot = buildCustomerSnapshot(customerProfile)
const orderSnapshot = buildOrderSnapshot(selections, products, categories)
const { data: modules } = await supabase
.from('product_modules')
.select('*')
.in('id', orderData.selected_modules)
if (!product) throw new Error('Product not found')
// 2. Create the Order in DB
// 2. Bestellung in DB schreiben
const { data: order, error: orderError } = await supabase
.from('orders')
.insert([{
user_id: user.id,
total_price: orderData.total_amount, // Matched column name in initial_schema.sql
order_data: {
product_id: orderData.product_id,
modules: orderData.selected_modules
},
customer_data: orderData.customer_details,
status: 'pending'
total_price: orderSnapshot.total,
customer_data: customerSnapshot,
order_data: orderSnapshot,
status: 'pending',
}])
.select()
.single()
if (orderError) throw orderError
// 3. Generate PDF
// 3. PDF generieren (greift auf Snapshot-Daten zu, nicht auf Live-Katalog)
try {
const buffer = await renderToBuffer(
React.createElement(InvoicePDF, {
order: order,
product: product,
modules: modules || [],
customer: orderData.customer_details
order,
customer: customerSnapshot,
orderSnapshot,
})
)
// 4. Upload to Supabase Storage
// 4. PDF in Supabase Storage hochladen
const fileName = `invoice_${order.id}.pdf`
const { data: uploadData, error: uploadError } = await supabase
const { error: uploadError } = await supabase
.storage
.from('invoices')
.upload(fileName, buffer, {
contentType: 'application/pdf',
upsert: true
})
.upload(fileName, buffer, { contentType: 'application/pdf', upsert: true })
if (uploadError) {
console.error('PDF Upload Error:', uploadError)
} else {
// 5. Update Order with PDF URL
const { data: publicUrlData } = supabase
.storage
.from('invoices')
.getPublicUrl(fileName)
await supabase
.from('orders')
.update({ pdf_url: publicUrlData.publicUrl })
.eq('id', order.id)
const { data: publicUrlData } = supabase.storage.from('invoices').getPublicUrl(fileName)
await supabase.from('orders').update({ pdf_url: publicUrlData.publicUrl }).eq('id', order.id)
}
} catch (pdfError) {
console.error('PDF Generation Error:', pdfError)
}
revalidatePath('/protected')
return order
return order as Order
}

View File

@@ -2,7 +2,7 @@
import { createClient } from '@/lib/supabase/server'
import { revalidatePath } from 'next/cache'
import { Product, ProductModule } from '../types'
import { Category, Product, ProductModule } from '../types'
export async function getProducts() {
const supabase = await createClient()
@@ -109,7 +109,6 @@ export async function updateProduct(id: string, product: Partial<Product>, modul
name: m.name,
description: m.description || null,
price: m.price,
is_required: m.is_required,
requirements: m.requirements || [],
exclusions: m.exclusions || [],
product_id: id