Muster-/Angebot-Endpunkte: WordPress-Feldnamen als Aliase akzeptieren
vorname→first_name, name→last_name, telefon→phone, zipcode→zip, ort→city, produkt_interesse→product. App-Feldnamen behalten Vorrang. So kann ein WordPress-Formular direkt Muster-/Angebotsanfragen anlegen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1423,16 +1423,20 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
// ── Angebotsanfrage („Individuelles Angebot") ────────────────────────────
|
||||
router.post('/offer-request', async (req, res) => {
|
||||
const body = req.body || {};
|
||||
const vorname = String(body.first_name || '').trim();
|
||||
const nachname = String(body.last_name || '').trim();
|
||||
const name = [vorname, nachname].filter(Boolean).join(' ') || String(body.name || '').trim();
|
||||
// Feld-Aliase (auch WordPress): vorname→first_name, name→last_name, telefon→phone,
|
||||
// produkt_interesse→product. App-Feldnamen haben Vorrang.
|
||||
const vorname = String(body.first_name ?? body.vorname ?? '').trim();
|
||||
const nachname = String(body.last_name ?? body.name ?? '').trim();
|
||||
const name = [vorname, nachname].filter(Boolean).join(' ');
|
||||
const phone = String(body.phone ?? body.telefon ?? '').trim();
|
||||
const product = String(body.product ?? body.produkt_interesse ?? '').trim();
|
||||
const email = norm(body.email);
|
||||
const message = String(body.message || '').trim();
|
||||
|
||||
const errors = [];
|
||||
if (!name) errors.push('Name fehlt.');
|
||||
if (!isEmail(email)) errors.push('Gültige E-Mail-Adresse fehlt.');
|
||||
if (!message && !body.product) errors.push('Bitte beschreiben Sie Ihr Vorhaben.');
|
||||
if (!message && !product) errors.push('Bitte beschreiben Sie Ihr Vorhaben.');
|
||||
if (message.length > 5000) errors.push('Beschreibung ist zu lang.');
|
||||
if (errors.length) return res.status(400).json({ errors });
|
||||
|
||||
@@ -1454,9 +1458,9 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
type: 'angebot',
|
||||
name: clean(name),
|
||||
email,
|
||||
phone: clean(String(body.phone || '').trim()) || null,
|
||||
phone: clean(phone) || null,
|
||||
quantity: Number.isFinite(quantity) && quantity > 0 ? quantity : null,
|
||||
product: body.product ? clean(String(body.product)) : null,
|
||||
product: product ? clean(product) : null,
|
||||
message: clean(message),
|
||||
address: (vorname || nachname) ? { first_name: clean(vorname), last_name: clean(nachname) } : null,
|
||||
status: 'neu',
|
||||
@@ -1464,7 +1468,7 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
});
|
||||
|
||||
// Schlanke interne Benachrichtigung.
|
||||
const produkt = body.product ? clean(String(body.product)) : null;
|
||||
const produkt = product ? clean(product) : null;
|
||||
await teamMail(schema, `Neue Angebotsanfrage: ${name}`,
|
||||
`<p>Neue Angebotsanfrage von <strong>${name}</strong> (${email}${body.phone ? `, ${clean(String(body.phone))}` : ''})`
|
||||
+ `${produkt ? ` · ${produkt}` : ''} – im Board unter „Neu".</p>`);
|
||||
@@ -1480,15 +1484,23 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
router.post('/sample-request', async (req, res) => {
|
||||
const body = req.body || {};
|
||||
const email = norm(body.email);
|
||||
// Vor-/Nachname getrennt; „name" bleibt als Fallback (Altstand/Kompatibilität).
|
||||
const vollName = [String(body.first_name || '').trim(), String(body.last_name || '').trim()].filter(Boolean).join(' ')
|
||||
|| String(body.name || '').trim();
|
||||
// Feld-Aliase, damit auch das WordPress-Formular direkt anlegen kann:
|
||||
// vorname→first_name, name→last_name, telefon→phone, zipcode→zip, ort→city,
|
||||
// produkt_interesse→product. Die App-Feldnamen haben Vorrang.
|
||||
const first = String(body.first_name ?? body.vorname ?? '').trim();
|
||||
const last = String(body.last_name ?? body.name ?? '').trim();
|
||||
const product = String(body.product ?? body.produkt_interesse ?? '').trim();
|
||||
const phone = String(body.phone ?? body.telefon ?? '').trim();
|
||||
const street = String(body.street ?? '').trim();
|
||||
const zip = String(body.zip ?? body.zipcode ?? '').trim();
|
||||
const city = String(body.city ?? body.ort ?? '').trim();
|
||||
const country = String(body.country ?? '').trim();
|
||||
const vollName = [first, last].filter(Boolean).join(' ');
|
||||
const errors = [];
|
||||
if (!body.product) errors.push('Produkt fehlt.');
|
||||
if (!product) errors.push('Produkt fehlt.');
|
||||
if (!vollName) errors.push('Name fehlt.');
|
||||
if (!isEmail(email)) errors.push('Gültige E-Mail-Adresse fehlt.');
|
||||
if (!String(body.street || '').trim() || !String(body.zip || '').trim() || !String(body.city || '').trim())
|
||||
errors.push('Lieferadresse unvollständig.');
|
||||
if (!street || !zip || !city) errors.push('Lieferadresse unvollständig.');
|
||||
if (errors.length) return res.status(400).json({ errors });
|
||||
|
||||
try {
|
||||
@@ -1505,16 +1517,16 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
type: 'muster',
|
||||
name: clean(vollName),
|
||||
email,
|
||||
phone: clean(String(body.phone || '').trim()) || null,
|
||||
product: clean(String(body.product)),
|
||||
phone: clean(phone) || null,
|
||||
product: clean(product),
|
||||
message: clean(String(body.message || '').trim().slice(0, 1000)) || null,
|
||||
address: {
|
||||
first_name: clean(String(body.first_name || '').trim()),
|
||||
last_name: clean(String(body.last_name || '').trim()),
|
||||
street: clean(String(body.street || '')),
|
||||
zip: clean(String(body.zip || '')),
|
||||
city: clean(String(body.city || '')),
|
||||
country: clean(String(body.country || '')),
|
||||
first_name: clean(first),
|
||||
last_name: clean(last),
|
||||
street: clean(street),
|
||||
zip: clean(zip),
|
||||
city: clean(city),
|
||||
country: clean(country),
|
||||
},
|
||||
status: 'neu',
|
||||
customer: customer?.id ?? null,
|
||||
@@ -1522,8 +1534,8 @@ const handler = (router, { services, getSchema, logger }) => {
|
||||
|
||||
const musterNachricht = clean(String(body.message || '').trim().slice(0, 1000));
|
||||
await teamMail(schema, `Neue Musteranfrage: ${clean(vollName)}`,
|
||||
`<p>Neue Musteranfrage von <strong>${clean(vollName)}</strong> (${email}${body.phone ? `, ${clean(String(body.phone))}` : ''})`
|
||||
+ ` · Produkt: ${clean(String(body.product))} – im Board unter „Neu".</p>`
|
||||
`<p>Neue Musteranfrage von <strong>${clean(vollName)}</strong> (${email}${phone ? `, ${clean(phone)}` : ''})`
|
||||
+ ` · Produkt: ${clean(product)} – im Board unter „Neu".</p>`
|
||||
+ (musterNachricht ? `<p><strong>Nachricht:</strong><br>${musterNachricht.replace(/\n/g, '<br>')}</p>` : ''));
|
||||
|
||||
return res.json({ ok: true });
|
||||
|
||||
Reference in New Issue
Block a user