feat(order): add net/tax/gross breakdown for one-time and monthly totals
All checks were successful
Staging Build / build (push) Successful in 3m28s
All checks were successful
Staging Build / build (push) Successful in 3m28s
This commit is contained in:
@@ -36,6 +36,18 @@ export default async function OrderSuccessPage({
|
||||
const o = order as Order
|
||||
const items = o.order_data?.items ?? []
|
||||
|
||||
const taxRate = o.order_data?.tax_rate ?? 19
|
||||
const oneTimeItems = items.filter((item) => item.billing_interval === 'one_time')
|
||||
const monthlyItems = items.filter((item) => item.billing_interval === 'monthly')
|
||||
|
||||
const oneTimeNet = oneTimeItems.reduce((sum, item) => 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, item) => sum + (item.item_total || 0), 0)
|
||||
const monthlyTax = Math.round(monthlyNet * (taxRate / 100) * 100) / 100
|
||||
const monthlyGross = Math.round((monthlyNet + monthlyTax) * 100) / 100
|
||||
|
||||
const statusLabel: Record<string, string> = {
|
||||
pending: 'Eingegangen',
|
||||
active: 'In Bearbeitung',
|
||||
@@ -104,12 +116,49 @@ export default async function OrderSuccessPage({
|
||||
<Separator className="bg-white/10" />
|
||||
|
||||
{/* Gesamtbetrag */}
|
||||
<div className="flex justify-between text-lg font-bold">
|
||||
<span className="text-slate-300">Gesamtbetrag</span>
|
||||
<span className="text-gradient">
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(o.total_price)}
|
||||
</span>
|
||||
</div>
|
||||
{oneTimeNet > 0 && (
|
||||
<div className="space-y-1">
|
||||
{monthlyNet > 0 && <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. {taxRate}% 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 Gesamtbetrag:</span>
|
||||
<span className={monthlyNet > 0 ? "text-white" : "text-gradient"}>
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{oneTimeNet > 0 && monthlyNet > 0 && (
|
||||
<Separator className="bg-white/5 my-2" />
|
||||
)}
|
||||
|
||||
{monthlyNet > 0 && (
|
||||
<div className="space-y-1">
|
||||
{oneTimeNet > 0 && <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)} / Monat</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm text-slate-400">
|
||||
<span>zzgl. {taxRate}% MwSt.:</span>
|
||||
<span>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / Monat</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-base font-bold text-white">
|
||||
<span>Brutto Gesamtbetrag:</span>
|
||||
<span className="text-gradient">
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / Monat
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{o.order_data?.price_multiplier !== null && o.order_data?.price_multiplier !== undefined && (
|
||||
<div className="text-sm text-green-400 font-semibold bg-green-500/10 p-3 rounded-lg border border-green-500/20 space-y-1">
|
||||
|
||||
Reference in New Issue
Block a user