import { Document, Page, Text, View, StyleSheet, Font } from '@react-pdf/renderer'; // Create styles const styles = StyleSheet.create({ page: { padding: 50, fontSize: 10, color: '#333', fontFamily: 'Helvetica', }, header: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 40, }, companyInfo: { textAlign: 'right', }, title: { fontSize: 24, color: '#000', marginBottom: 20, }, section: { marginBottom: 20, }, label: { fontSize: 8, color: '#999', textTransform: 'uppercase', marginBottom: 2, }, table: { width: 'auto', borderStyle: 'solid', borderWidth: 1, borderColor: '#eee', borderRightWidth: 0, borderBottomWidth: 0, marginBottom: 20, }, tableRow: { margin: 'auto', flexDirection: 'row', }, tableCol: { width: '60%', borderStyle: 'solid', borderWidth: 1, borderColor: '#eee', borderLeftWidth: 0, borderTopWidth: 0, padding: 8, }, tableColPrice: { width: '40%', borderStyle: 'solid', borderWidth: 1, borderColor: '#eee', borderLeftWidth: 0, borderTopWidth: 0, padding: 8, textAlign: 'right', }, tableCell: { margin: 'auto', marginTop: 5, fontSize: 10, }, total: { flexDirection: 'row', justifyContent: 'flex-end', marginTop: 20, borderTop: 1, borderColor: '#000', paddingTop: 10, }, totalLabel: { fontSize: 14, fontWeight: 'bold', }, footer: { position: 'absolute', bottom: 30, left: 50, right: 50, textAlign: 'center', color: '#999', fontSize: 8, borderTop: 1, borderColor: '#eee', paddingTop: 10, }, }); export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => { const items = orderSnapshot?.items ?? []; const taxRate = orderSnapshot?.tax_rate ?? 19; const oneTimeItems = items.filter((item: any) => item.billing_interval === 'one_time'); const monthlyItems = items.filter((item: any) => item.billing_interval === 'monthly'); const oneTimeNet = oneTimeItems.reduce((sum: number, item: any) => sum + (item.item_total || 0), 0); const oneTimeTax = Math.round(oneTimeNet * (taxRate / 100) * 100) / 100; const oneTimeGross = Math.round((oneTimeNet + oneTimeTax) * 100) / 100; const monthlyNet = monthlyItems.reduce((sum: number, item: any) => sum + (item.item_total || 0), 0); const monthlyTax = Math.round(monthlyNet * (taxRate / 100) * 100) / 100; const monthlyGross = Math.round((monthlyNet + monthlyTax) * 100) / 100; return ( CASPOS Software Solutions CASPOS Computerabrechnungssysteme GmbH Alte Bundesstraße 16 76846 Hauenstein Deutschland Anfragebestätigung Anfragender Kunde {customer.company_name} {customer.first_name} {customer.last_name} {customer.address} {customer.zip_code} {customer.city} USt-IdNr: {customer.vat_id} {customer.bank_iban && ( Bank: {customer.bank_name || '-'} · IBAN: {customer.bank_iban} · BIC: {customer.bank_bic || '-'} · Inhaber: {customer.bank_owner || '-'} )} Anfragedetails Anfrage-Nummer: {order.order_number || order.id} Datum: {new Date(order.created_at || Date.now()).toLocaleDateString('de-DE')} {orderSnapshot?.price_multiplier !== null && orderSnapshot?.price_multiplier !== undefined && ( Update-Konditionen {orderSnapshot.price_multiplier === 0 ? "Update (0-12 Monate): 100% Rabatt (inklusive)" : orderSnapshot.price_multiplier === 0.15 ? "Update (13-14 Monate): 15% vom Listenpreis" : orderSnapshot.price_multiplier === 0.30 ? "Update (15-25 Monate): 30% vom Listenpreis" : orderSnapshot.price_multiplier === 0.45 ? "Update (26-37 Monate): 45% vom Listenpreis" : orderSnapshot.price_multiplier === 0.60 ? "Update (38-49 Monate): 60% vom Listenpreis" : orderSnapshot.price_multiplier === 0.90 ? "Neukauf (>= 50 Monate): 10% Rabatt auf Neukauf" : `Gebühr: ${orderSnapshot.price_multiplier * 100}%`} {orderSnapshot.last_license_date && ( Letzte Lizenz vom: {new Date(orderSnapshot.last_license_date).toLocaleDateString('de-DE')} )} )} Beschreibung Preis (netto) {items.map((item: any, idx: number) => ( {item.product_name} ({item.category_name}) {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(item.base_price)} {' '}{item.billing_interval === 'one_time' ? 'einmalig' : 'mtl.'} {item.selected_modules?.map((mod: any, mIdx: number) => { const qty = mod.quantity || 1; const price = mod.total_price ?? (mod.price * qty); const hasQty = qty > 1; return ( + {mod.module_name} {hasQty ? `(x${qty})` : ''} +{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price)} ); })} ))} {oneTimeNet > 0 && ( 0 ? 10 : 0 }}> {monthlyNet > 0 && ( Einmaliger Betrag: )} Netto-Zwischensumme: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)} zzgl. {taxRate}% USt: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)} {monthlyNet > 0 ? 'Gesamtbetrag einmalig (brutto):' : 'Gesamtbetrag (brutto):'} {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)} )} {oneTimeNet > 0 && monthlyNet > 0 && ( )} {monthlyNet > 0 && ( {oneTimeNet > 0 && ( Monatlicher Betrag: )} Netto-Zwischensumme: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl. zzgl. {taxRate}% USt: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl. {oneTimeNet > 0 ? 'Gesamtbetrag monatlich (brutto):' : 'Gesamtbetrag (brutto):'} {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl. )} Vielen Dank für Ihre Bestellung! Dies ist ein automatisch generiertes Dokument. ); };