feat(email): include order item configurations in confirmation email
All checks were successful
Staging Build / build (push) Successful in 2m54s

This commit is contained in:
DanielS
2026-07-10 08:57:52 +02:00
parent d8b7076e7e
commit bc6487bba4
2 changed files with 80 additions and 4 deletions

View File

@@ -16,6 +16,69 @@ import { getOrderEmailTemplate, getStatusEmailTemplate } from '@/lib/actions/ema
// ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
function buildEmailItemsSection(items: any[]) {
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)
})
let itemsDetailsText = '\nKassen-Konfigurationen:'
let itemsDetailsHtml = `
<tr>
<td colspan="2" style="padding: 12px 0 6px 0; border-top: 1px solid #e2e8f0; font-weight: bold; color: #0f172a;">Kassen-Konfigurationen:</td>
</tr>
`
Object.entries(groupedItems).forEach(([deviceName, devItems]) => {
itemsDetailsText += `\n- Kasse: \${deviceName}`
itemsDetailsHtml += `
<tr style="background-color: #f1f5f9;">
<td colspan="2" style="padding: 6px 8px; font-weight: bold; color: #1e3a8a; font-size: 13px;">Kasse: \${deviceName}</td>
</tr>
`
devItems.forEach((item: any) => {
itemsDetailsText += `\n * \${item.product_name} (\${item.category_name}): \${item.base_price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })} \${item.billing_interval === 'one_time' ? 'einmalig' : 'mtl.'}`
itemsDetailsHtml += `
<tr>
<td style="padding: 6px 8px; font-size: 13px; color: #334155; font-weight: 500;">
\${item.product_name} <span style="font-size: 11px; color: #64748b;">(\${item.category_name})</span>
</td>
<td style="padding: 6px 8px; text-align: right; font-size: 13px; font-weight: bold; color: #0f172a;">
\${item.base_price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })} \${item.billing_interval === 'one_time' ? 'einmalig' : 'mtl.'}
</td>
</tr>
`
item.selected_modules?.forEach((mod: any) => {
const qty = mod.quantity || 1
const price = mod.total_price ?? (mod.price * qty)
itemsDetailsText += `\n + \${mod.module_name} \${qty > 1 ? \`(x\${qty})\` : ''}: +\${price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })} mtl.`
itemsDetailsHtml += `
<tr>
<td style="padding: 4px 8px 4px 20px; color: #64748b; font-size: 12px;">
+ \${mod.module_name} \${qty > 1 ? \`<span style="font-size: 10px; font-weight: 600;">(x\${qty})</span>\` : ''}
</td>
<td style="padding: 4px 8px; text-align: right; color: #64748b; font-size: 12px;">
+\${price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })} mtl.
</td>
</tr>
`
})
})
})
return {
text: itemsDetailsText + '\n',
html: itemsDetailsHtml
}
}
/**
* Erzeugt eine menschenlesbare, nicht-sequenzielle Bestellnummer.
* Format: BE-YYYY-NNNNN (z.B. BE-2026-84731)
@@ -256,12 +319,16 @@ export async function submitOrder(params: {
`
}
const itemsSection = buildEmailItemsSection(items)
const emailTemplate = getOrderEmailTemplate({
orderNumber,
formattedDate,
customerCompanyName: customerSnapshot.company_name,
totalDetailsText,
totalDetailsHtml
totalDetailsHtml,
itemsDetailsText: itemsSection.text,
itemsDetailsHtml: itemsSection.html
}, `${process.env.NEXT_PUBLIC_SITE_URL || 'https://staging.hephex.de'}`, false)
await sendMail({
@@ -577,12 +644,16 @@ export async function updateOrder(
`
}
const itemsSection = buildEmailItemsSection(items)
const emailTemplate = getOrderEmailTemplate({
orderNumber: order.order_number,
formattedDate,
customerCompanyName: customerSnapshot.company_name,
totalDetailsText,
totalDetailsHtml
totalDetailsHtml,
itemsDetailsText: itemsSection.text,
itemsDetailsHtml: itemsSection.html
}, `${process.env.NEXT_PUBLIC_SITE_URL || 'https://staging.hephex.de'}`, true)
await sendMail({