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:
@@ -96,10 +96,18 @@ const styles = StyleSheet.create({
|
||||
|
||||
export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
|
||||
const items = orderSnapshot?.items ?? [];
|
||||
const subtotal = orderSnapshot?.subtotal ?? 0;
|
||||
const taxAmount = orderSnapshot?.tax_amount ?? 0;
|
||||
const taxRate = orderSnapshot?.tax_rate ?? 19;
|
||||
const total = orderSnapshot?.total ?? 0;
|
||||
|
||||
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 (
|
||||
<Document>
|
||||
@@ -204,18 +212,57 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
|
||||
|
||||
<View style={styles.total}>
|
||||
<View style={{ width: '50%' }}>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>Netto-Zwischensumme:</Text>
|
||||
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(subtotal)}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>zzgl. {taxRate}% USt:</Text>
|
||||
<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 (brutto):</Text>
|
||||
<Text style={styles.totalLabel}>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(total)}</Text>
|
||||
</View>
|
||||
{oneTimeNet > 0 && (
|
||||
<View style={{ marginBottom: monthlyNet > 0 ? 10 : 0 }}>
|
||||
{monthlyNet > 0 && (
|
||||
<Text style={{ fontWeight: 'bold', marginBottom: 4, fontSize: 11 }}>Einmaliger Betrag:</Text>
|
||||
)}
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>Netto-Zwischensumme:</Text>
|
||||
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeNet)}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>zzgl. {taxRate}% USt:</Text>
|
||||
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeTax)}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 5, borderTopWidth: 1, borderTopColor: '#000', paddingTop: 5 }}>
|
||||
<Text style={styles.totalLabel}>
|
||||
{monthlyNet > 0 ? 'Gesamtbetrag einmalig (brutto):' : 'Gesamtbetrag (brutto):'}
|
||||
</Text>
|
||||
<Text style={styles.totalLabel}>
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(oneTimeGross)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{oneTimeNet > 0 && monthlyNet > 0 && (
|
||||
<View style={{ borderTopWidth: 1, borderTopColor: '#eee', marginVertical: 10 }} />
|
||||
)}
|
||||
|
||||
{monthlyNet > 0 && (
|
||||
<View>
|
||||
{oneTimeNet > 0 && (
|
||||
<Text style={{ fontWeight: 'bold', marginBottom: 4, fontSize: 11 }}>Monatlicher Betrag:</Text>
|
||||
)}
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>Netto-Zwischensumme:</Text>
|
||||
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyNet)} / mtl.</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 3 }}>
|
||||
<Text>zzgl. {taxRate}% USt:</Text>
|
||||
<Text>{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyTax)} / mtl.</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 5, borderTopWidth: 1, borderTopColor: '#000', paddingTop: 5 }}>
|
||||
<Text style={styles.totalLabel}>
|
||||
{oneTimeNet > 0 ? 'Gesamtbetrag monatlich (brutto):' : 'Gesamtbetrag (brutto):'}
|
||||
</Text>
|
||||
<Text style={styles.totalLabel}>
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(monthlyGross)} / mtl.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user