feat: group items by device name in pdf quotation confirmation
All checks were successful
Staging Build / build (push) Successful in 2m47s

This commit is contained in:
DanielS
2026-07-09 23:53:58 +02:00
parent db95e435c2
commit 1e7112fa3c
2 changed files with 45 additions and 25 deletions

View File

@@ -149,7 +149,11 @@ export async function checkoutAction(params: {
type === 'purchase' ? 'one_time' : 'monthly',
item.moduleQuantities
);
orderItemsList.push(...itemSnapshot.items);
const itemsWithDevice = itemSnapshot.items.map(i => ({
...i,
device_name: item.deviceName
}));
orderItemsList.push(...itemsWithDevice);
total += itemSnapshot.total;
}

View File

@@ -106,6 +106,15 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
const formattedPrice = (val: number) =>
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(val);
const groupedItems: { [key: string]: any[] } = {};
items.forEach((item: any) => {
const devName = item.device_name || 'Kasse 1';
if (!groupedItems[devName]) {
groupedItems[devName] = [];
}
groupedItems[devName].push(item);
});
return (
<Document>
<Page size="A4" style={styles.page}>
@@ -148,36 +157,43 @@ export const InvoicePDF = ({ order, orderSnapshot, customer }: any) => {
<View style={styles.tableColPrice}><Text style={{ fontWeight: 'bold' }}>Preis (netto)</Text></View>
</View>
{items.map((item: any, idx: number) => (
<View key={idx}>
<View style={styles.tableRow}>
<View style={styles.tableCol}>
<Text style={{ fontWeight: 'bold' }}>{item.product_name} ({item.category_name})</Text>
</View>
<View style={styles.tableColPrice}>
<Text>
{formattedPrice(item.base_price)} {isSubscription ? 'mtl.' : 'einmalig'}
</Text>
</View>
{Object.entries(groupedItems).map(([deviceName, devItems], groupIdx) => (
<View key={groupIdx} style={{ marginBottom: 6 }}>
<View style={{ backgroundColor: '#f1f5f9', padding: '4 8', marginTop: 6, borderBottomWidth: 1, borderBottomColor: '#cbd5e1' }}>
<Text style={{ fontSize: 9, fontWeight: 'bold', color: '#1e293b' }}>Gerät: {deviceName}</Text>
</View>
{item.selected_modules?.map((mod: any, mIdx: number) => {
const qty = mod.quantity || 1;
const price = mod.total_price ?? (mod.price * qty);
return (
<View key={mIdx} style={styles.tableRow}>
<View style={[styles.tableCol, { paddingLeft: 20 }]}>
<Text style={{ color: '#666' }}>
+ {mod.module_name} {qty > 1 ? `(x${qty})` : ''}
</Text>
{devItems.map((item: any, idx: number) => (
<View key={idx}>
<View style={styles.tableRow}>
<View style={styles.tableCol}>
<Text style={{ fontWeight: 'bold' }}>{item.product_name} ({item.category_name})</Text>
</View>
<View style={styles.tableColPrice}>
<Text style={{ color: '#666' }}>
+{formattedPrice(price)}
<Text>
{formattedPrice(item.base_price)} {isSubscription ? 'mtl.' : 'einmalig'}
</Text>
</View>
</View>
);
})}
{item.selected_modules?.map((mod: any, mIdx: number) => {
const qty = mod.quantity || 1;
const price = mod.total_price ?? (mod.price * qty);
return (
<View key={mIdx} style={styles.tableRow}>
<View style={[styles.tableCol, { paddingLeft: 20 }]}>
<Text style={{ color: '#666' }}>
+ {mod.module_name} {qty > 1 ? `(x${qty})` : ''}
</Text>
</View>
<View style={styles.tableColPrice}>
<Text style={{ color: '#666' }}>
+{formattedPrice(price)}
</Text>
</View>
</View>
);
})}
</View>
))}
</View>
))}
</View>