fix: fix overlapping PDF labels and show net tax gross prices in wizard
All checks were successful
Staging Build / build (push) Successful in 3m25s

This commit is contained in:
DanielS
2026-07-03 01:13:16 +02:00
parent e67695e36e
commit 147dab5607
2 changed files with 118 additions and 51 deletions

View File

@@ -213,10 +213,7 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(taxAmount)}</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 5, borderTopWidth: 1, borderTopColor: '#000', paddingTop: 5 }}>
<Text style={styles.totalLabel}>Gesamtbetrag (netto):</Text>
<Text style={styles.totalLabel}>MwSt.Betrag:</Text>
<Text style={styles.totalLabel}>Gesamtbetrag (brutto):</Text>
<Text style={styles.totalLabel}>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(total)}</Text>
</View>
</View>

View File

@@ -294,6 +294,14 @@ export function OrderWizard({
return { monthlyTotal: monthly, oneTimeTotal: oneTime }
}, [selections, products, categories, moduleQuantities, updatePriceModifier])
const oneTimeNet = oneTimeTotal
const oneTimeTax = oneTimeNet * 0.19
const oneTimeGross = oneTimeNet + oneTimeTax
const monthlyNet = monthlyTotal
const monthlyTax = monthlyNet * 0.19
const monthlyGross = monthlyNet + monthlyTax
// Helper: update product selection for a category (resets modules)
function selectProduct(catId: string, productId: string) {
setSelections(prev => {
@@ -981,35 +989,67 @@ export function OrderWizard({
})}
<Separator className="bg-white/10" />
{oneTimeTotal > 0 && monthlyTotal > 0 ? (
<div className="space-y-2">
<div className="flex justify-between text-base font-semibold text-white">
<span className="text-slate-400">Einmalig gesamt:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTotal)}
</span>
<div className="space-y-3">
<div className="space-y-1">
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Einmalig:</p>
<div className="flex justify-between text-xs text-slate-400">
<span>Netto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)}</span>
</div>
<div className="flex justify-between text-xs text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)}</span>
</div>
<div className="flex justify-between text-sm font-bold text-white">
<span>Gesamt (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}</span>
</div>
</div>
<div className="space-y-1 pt-2 border-t border-white/10">
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Monatlich:</p>
<div className="flex justify-between text-xs text-slate-400">
<span>Netto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl.</span>
</div>
<div className="flex justify-between text-xs text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl.</span>
</div>
<div className="flex justify-between text-sm font-bold text-white">
<span>Gesamt (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl.</span>
</div>
<div className="flex justify-between text-base font-semibold text-white">
<span className="text-slate-400">Monatlich gesamt:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTotal)}
{' '}<span className="text-xs font-normal text-slate-400">/ Monat</span>
</span>
</div>
</div>
) : oneTimeTotal > 0 ? (
<div className="flex justify-between text-xl font-bold text-gradient">
<span>Gesamt (einmalig):</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTotal)}
</span>
<div className="space-y-1">
<div className="flex justify-between text-xs text-slate-400">
<span>Netto-Gesamtbetrag:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)}</span>
</div>
<div className="flex justify-between text-xs text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)}</span>
</div>
<div className="flex justify-between text-base font-bold text-gradient">
<span>Gesamtbetrag (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}</span>
</div>
</div>
) : (
<div className="flex justify-between text-xl font-bold text-gradient">
<span>Gesamt:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTotal)}
{' '}<span className="text-sm font-normal text-slate-400">/ Monat</span>
</span>
<div className="space-y-1">
<div className="flex justify-between text-xs text-slate-400">
<span>Netto-Gesamtbetrag:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl.</span>
</div>
<div className="flex justify-between text-xs text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl.</span>
</div>
<div className="flex justify-between text-base font-bold text-gradient">
<span>Gesamtbetrag (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl.</span>
</div>
</div>
)}
{updatePriceModifier.label && (
@@ -1139,47 +1179,77 @@ export function OrderWizard({
</div>
</div>
{oneTimeTotal > 0 && monthlyTotal > 0 ? (
<div className="space-y-2 border-t border-white/10 pt-4">
<div className="flex justify-between text-lg font-bold text-white">
<span className="text-slate-400">Einmaliger Gesamtbetrag:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTotal)}
</span>
<div className="space-y-4 border-t border-white/10 pt-4">
<div className="space-y-1">
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Einmaliger Betrag:</p>
<div className="flex justify-between text-sm text-slate-400">
<span>Netto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)}</span>
</div>
<div className="flex justify-between text-sm text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)}</span>
</div>
<div className="flex justify-between text-base font-bold text-white">
<span>Brutto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}</span>
</div>
</div>
{updatePriceModifier.label && (
<div className="text-sm text-green-400 font-semibold bg-green-500/10 p-2 rounded border border-green-500/20 my-1">
{updatePriceModifier.label}
</div>
)}
<div className="flex justify-between text-lg font-bold text-white">
<span className="text-slate-400">Monatlicher Gesamtbetrag:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTotal)}
{' '}<span className="text-sm font-normal text-slate-400">/ Monat</span>
</span>
<div className="space-y-1 pt-2 border-t border-white/10">
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Monatlicher Betrag:</p>
<div className="flex justify-between text-sm text-slate-400">
<span>Netto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl.</span>
</div>
<div className="flex justify-between text-sm text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl.</span>
</div>
<div className="flex justify-between text-base font-bold text-white">
<span>Brutto:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl.</span>
</div>
</div>
</div>
) : oneTimeTotal > 0 ? (
<div className="flex flex-col border-t border-white/10 pt-4 gap-1.5">
<div className="flex justify-between text-xl font-bold text-gradient">
<span>Gesamtbetrag:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTotal)}
</span>
<div className="space-y-1 border-t border-white/10 pt-4">
<div className="flex justify-between text-sm text-slate-400">
<span>Netto-Gesamtbetrag:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)}</span>
</div>
<div className="flex justify-between text-sm text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)}</span>
</div>
{updatePriceModifier.label && (
<div className="text-sm text-green-400 font-semibold bg-green-500/10 p-2 rounded border border-green-500/20 self-end">
<div className="text-sm text-green-400 font-semibold bg-green-500/10 p-2 rounded border border-green-500/20 my-1">
{updatePriceModifier.label}
</div>
)}
<div className="flex justify-between text-xl font-bold text-gradient pt-1 border-t border-white/5">
<span>Gesamtbetrag (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}</span>
</div>
</div>
) : (
<div className="flex justify-between text-xl font-bold text-gradient border-t border-white/10 pt-4">
<span>Gesamtbetrag:</span>
<span>
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTotal)}
{' '}<span className="text-sm font-normal text-slate-400">/ Monat</span>
</span>
<div className="space-y-1 border-t border-white/10 pt-4">
<div className="flex justify-between text-sm text-slate-400">
<span>Netto-Gesamtbetrag:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl.</span>
</div>
<div className="flex justify-between text-sm text-slate-400">
<span>zzgl. 19% MwSt.:</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl.</span>
</div>
<div className="flex justify-between text-xl font-bold text-gradient pt-1 border-t border-white/5">
<span>Gesamtbetrag (brutto):</span>
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl.</span>
</div>
</div>
)}
<p className="text-xs text-slate-500 italic">