fix(build): move buildEmailItemsSection to email-templates.ts to fix Turbopack build failure
Some checks failed
Staging Build / build (push) Failing after 25s
Some checks failed
Staging Build / build (push) Failing after 25s
This commit is contained in:
@@ -85,3 +85,66 @@ export function getStatusEmailTemplate(orderNumber: string, oldLabel: string, ne
|
|||||||
|
|
||||||
return { text, html }
|
return { text, html }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,71 +12,10 @@ import { buildCustomerSnapshot, buildOrderSnapshot } from '@/lib/license-transfo
|
|||||||
import type { Category, EndCustomer, Order, Product, Profile, WizardSelections } from '@/lib/types'
|
import type { Category, EndCustomer, Order, Product, Profile, WizardSelections } from '@/lib/types'
|
||||||
import { getProducts, getCategories } from '@/lib/actions/products'
|
import { getProducts, getCategories } from '@/lib/actions/products'
|
||||||
import { validateWizardSelections } from '@/lib/actions/validation'
|
import { validateWizardSelections } from '@/lib/actions/validation'
|
||||||
import { getOrderEmailTemplate, getStatusEmailTemplate } from '@/lib/actions/email-templates'
|
import { getOrderEmailTemplate, getStatusEmailTemplate, buildEmailItemsSection } from '@/lib/actions/email-templates'
|
||||||
|
|
||||||
// ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
|
// ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user