From 25547df81536151c2dbcd2a2ec5e7ed92a10b106 Mon Sep 17 00:00:00 2001 From: s4luorth Date: Fri, 18 Sep 2026 12:17:21 +0200 Subject: [PATCH] Konfigurator: Platzhalter sicher ersetzen + Anrede kein Standard-Platzhalter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Standard-Platzhalter (Vorname/Nachname/Strasse/PLZ/Ort/Land) werden beim Senden je Empfänger explizit aufgelöst (standardWert) und mit den eigenen Platzhaltern in entries.placeholders geschrieben – so wird zuverlässig ersetzt (Vorschau + Bestellung). - „Anrede" aus STANDARD_STRUKTUR entfernt (kein Empfängerfeld dafür) → [[Anrede]] ist jetzt ein frei befüllbarer eigener Platzhalter statt fälschlich als Standard. Co-Authored-By: Claude Opus 4.8 --- src/routes/Configurator.tsx | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/routes/Configurator.tsx b/src/routes/Configurator.tsx index 1ac69ef..4fdde24 100644 --- a/src/routes/Configurator.tsx +++ b/src/routes/Configurator.tsx @@ -44,8 +44,10 @@ const PRODUKT_TEXT: Record = { follow_ups: 'Automatisierte handschriftliche Nachfass-Mailings für mehr Rücklauf.', }; -/** Standard-Platzhalter der strukturierten Adresse (werden automatisch befüllt). */ -const STANDARD_STRUKTUR = ['Anrede', 'Vorname', 'Nachname', 'Strasse', 'PLZ', 'Ort', 'Land']; +/** Standard-Platzhalter der strukturierten Adresse (werden automatisch befüllt). + * Ohne „Anrede" – dafür gibt es kein Empfängerfeld; als [[Anrede]] ist es ein + * frei befüllbarer eigener Platzhalter. */ +const STANDARD_STRUKTUR = ['Vorname', 'Nachname', 'Strasse', 'PLZ', 'Ort', 'Land']; /** Standard-Platzhalter der Freitext-Adresse. */ const STANDARD_FREITEXT = ['Zeile1', 'Zeile2', 'Zeile3', 'Zeile4', 'Zeile5']; @@ -792,6 +794,22 @@ export default function Configurator({ vorwahlProdukt }: { vorwahlProdukt?: stri const eigeneImText = genutztePlatzhalter.filter((p) => !standardSet.has(p.toLowerCase())); /** Platzhalter im individuellen Umschlagtext – analog zur Text-Tabelle. */ const genutztePlatzhalterUmschlag = useMemo(() => textPlatzhalter(umschlagText), [umschlagText]); + /** + * Entry für den Versand ans Backend: löst ALLE im Text/Umschlag genutzten + * Platzhalter explizit auf (Standard-Platzhalter aus der Adresse via standardWert, + * eigene aus e.placeholders). So wird je Empfänger sicher ersetzt – unabhängig + * davon, wie das Backend die Adressfelder interpretiert. + */ + const mitPlatzhaltern = (e: Entry): Entry => { + const used = [...new Set([...genutztePlatzhalter, ...genutztePlatzhalterUmschlag])]; + return { + ...e, + placeholders: { + ...Object.fromEntries(used.map((p) => [p, standardWert(e, p)])), + ...e.placeholders, + }, + }; + }; /** * Werden Platzhalterwerte NICHT bereits in einem Empfänger-Schritt erfasst * (kein Adress-Schritt, kein Umschlag-Freitext)? Dann muss der Text-Schritt @@ -932,7 +950,7 @@ export default function Configurator({ vorwahlProdukt }: { vorwahlProdukt?: stri realistic: realistisch, envelope_labeling: needsEnvelope ? labeling : 'keine', envelope_text: umschlagText, - entries: entries.slice(0, 3), + entries: entries.slice(0, 3).map(mitPlatzhaltern), }); if (r.has_overflow) { setTextUeberlauf(true); @@ -1090,7 +1108,7 @@ export default function Configurator({ vorwahlProdukt }: { vorwahlProdukt?: stri city: e.city, country: e.country, free_text: adressModus === 'freitext' ? e.free_text : '', - placeholders: e.placeholders, + placeholders: mitPlatzhaltern(e).placeholders, // Abweichender Text nur, wenn wirklich gesetzt (sonst greift der Standardtext). text: (e.text && e.text.trim()) ? e.text : undefined, })),