Neuauftrag: Stückzahl statt Empfängerzeilen bei identischem Druck ohne Kuvert

Ohne Kuvert (kein Postkarten-Format, „Kuverts generieren" aus) und ohne
eigene [[Platzhalter]] im Brieftext sind alle Schriftstücke identisch –
Empfängeradressen sind dort unnötig. Statt N Zeilen anzulegen, gibt es
jetzt ein Feld „Anzahl identischer Schriftstücke"; beim Anlegen werden
entsprechend viele gleiche Schriftstücke erzeugt. Sobald Kuverts aktiv
sind oder der Text eigene Platzhalter enthält, erscheint wieder die
Empfängertabelle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
s4luorth
2026-09-21 12:09:58 +02:00
parent 4d60a5d1da
commit af63fd66be

View File

@@ -81,6 +81,8 @@ const NeuAuftrag = defineComponent({
mehrseitig: false, seitenInfo: '',
// Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig).
adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()],
// Ohne Kuvert & ohne eigene Platzhalter: einfach N identische Schriftstücke.
anzahl: 1,
importOpen: false, importText: '',
docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '', lbDoc: null,
});
@@ -239,6 +241,12 @@ const NeuAuftrag = defineComponent({
const entries = () => neu.rows.filter((e) => String(e.free_text || '').trim()
|| felderGefuellt(e)
|| (e.placeholders && Object.values(e.placeholders).some((v) => String(v || '').trim())));
// Ohne Kuvert (und keine Postkarte) sind Empfängeradressen unnötig. Hat der Text
// zudem keine eigenen Platzhalter, sind alle Schriftstücke identisch → dann genügt
// eine Stückzahl statt einzelner Empfängerzeilen.
const keinKuvert = () => !istPostkarte() && !neu.kuverts;
const identischModus = () => keinKuvert() && customPlaceholders().length === 0;
const anzahlNorm = () => Math.max(1, Math.min(1000, Math.round(Number(neu.anzahl) || 1)));
// Aus Excel/CSV eingefügte Zeilen übernehmen. Erst die individuellen
// Platzhalter-Spalten, dann die Adresszeilen (Tab/Semikolon/Komma-getrennt).
@@ -382,9 +390,15 @@ const NeuAuftrag = defineComponent({
neu.msg = `✓ Auftrag ${nr} angelegt – Dokumente werden noch generiert. Status im Produktions-Board prüfen.`;
}
async function absenden() {
// Empfänger sind optional – ohne Empfänger genau ein Schriftstück (Blankozeile).
const ent = entries();
const payloadEntries = ent.length ? ent : [leereZeile()];
// Ohne Kuvert & ohne eigene Platzhalter: N identische Schriftstücke (Blankozeilen).
// Sonst: die erfassten Empfänger – ohne Empfänger genau ein Schriftstück.
let payloadEntries;
if (identischModus()) {
payloadEntries = Array.from({ length: anzahlNorm() }, () => leereZeile());
} else {
const ent = entries();
payloadEntries = ent.length ? ent : [leereZeile()];
}
neu.err = ''; neu.msg = 'Wird angelegt …';
try {
const kv = kuvertPayload();
@@ -415,6 +429,7 @@ const NeuAuftrag = defineComponent({
fontSizeLetter: 100, fontSizeEnvelope: 100,
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, mehrseitig: false, seitenInfo: '',
adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()],
anzahl: 1,
importOpen: false, importText: '',
docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '',
});
@@ -543,17 +558,29 @@ const NeuAuftrag = defineComponent({
const b2 = h('div', { style: BEREICH }, [
h('div', { style: 'display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px;' }, [
bereichKopf('✉ Kuvert'),
h('div', { style: 'width:420px;max-width:100%;' }, [segToggle(neu.adressModus, [{ key: '5zeilen', label: '5 Zeilen' }, { key: 'felder', label: 'Einzelfelder' }, { key: 'individuell', label: 'Ind. Text' }], (k) => { neu.adressModus = k; neu.previewSession = null; })]),
identischModus() ? null : h('div', { style: 'width:420px;max-width:100%;' }, [segToggle(neu.adressModus, [{ key: '5zeilen', label: '5 Zeilen' }, { key: 'felder', label: 'Einzelfelder' }, { key: 'individuell', label: 'Ind. Text' }], (k) => { neu.adressModus = k; neu.previewSession = null; })]),
]),
h('div', { style: 'display:flex;flex-direction:column;gap:8px;max-height:34vh;overflow:auto;' },
neu.rows.map((e, i) => h('div', { style: 'display:flex;gap:8px;align-items:center;' }, [
h('span', { style: `min-width:22px;font-weight:700;color:${ACCENT};` }, `#${i + 1}`),
h('div', { style: 'flex:1;min-width:0;display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;' }, zeile(e, i)),
h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:var(--danger,#c62828);font-size:18px;padding:2px 6px;' }, '×'),
]))),
h('div', { style: 'margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:12px;' }, [
btn('+ Empfänger', addZeile),
btn(neu.importOpen ? 'Import schließen' : '⇪ Aus Excel einfügen', () => { neu.importOpen = !neu.importOpen; }),
// Ohne Kuvert & ohne eigene Platzhalter genügt eine Stückzahl (identische
// Schriftstücke). Sonst die Empfängertabelle mit Zeilen/Import.
identischModus() ? h('div', {}, [
label('Anzahl identischer Schriftstücke'),
h('input', { type: 'number', min: 1, max: 1000, step: 1, value: neu.anzahl, style: WFELD + 'width:170px;',
onInput: (e) => { neu.anzahl = e.target.value; neu.previewSession = null; },
onBlur: (e) => { const n = Math.round(Number(e.target.value)); neu.anzahl = (Number.isFinite(n) && n) ? Math.max(1, Math.min(1000, n)) : 1; } }),
h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:6px;line-height:1.5;' },
'Ohne Kuvert werden keine Empfängeradressen gebraucht – es entstehen so viele gleiche Schriftstücke wie angegeben. '
+ 'Sobald „Kuverts generieren" aktiv ist oder der Text eigene [[Platzhalter]] enthält, erscheint wieder die Empfängertabelle.'),
]) : h('div', {}, [
h('div', { style: 'display:flex;flex-direction:column;gap:8px;max-height:34vh;overflow:auto;' },
neu.rows.map((e, i) => h('div', { style: 'display:flex;gap:8px;align-items:center;' }, [
h('span', { style: `min-width:22px;font-weight:700;color:${ACCENT};` }, `#${i + 1}`),
h('div', { style: 'flex:1;min-width:0;display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;' }, zeile(e, i)),
h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:var(--danger,#c62828);font-size:18px;padding:2px 6px;' }, '×'),
]))),
h('div', { style: 'margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:12px;' }, [
btn('+ Empfänger', addZeile),
btn(neu.importOpen ? 'Import schließen' : '⇪ Aus Excel einfügen', () => { neu.importOpen = !neu.importOpen; }),
]),
]),
// Postkarte: Hinweis auf das Kartenlayout; kein separates Kuvert.
istPostkarte() ? h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:12px;line-height:1.5;' },
@@ -583,7 +610,7 @@ const NeuAuftrag = defineComponent({
h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' },
istPostkarte() ? 'Empfänger steht darunter in der Anschriftzone (rechte Hälfte).' : 'Der Empfänger rutscht dann auf dem Kuvert automatisch nach unten rechts.'),
]) : null,
neu.importOpen ? h('div', { style: 'margin-top:12px;' }, [
(neu.importOpen && !identischModus()) ? h('div', { style: 'margin-top:12px;' }, [
subdued('Aus Excel kopieren und einfügen – eine Zeile pro Empfänger, Spalten mit Tab/Semikolon/Komma. '
+ 'Reihenfolge: erst individuelle Platzhalter, dann ' + (neu.adressModus === 'individuell' ? 'die eine Adresszeile.' : 'Zeile 1–5.'), 'margin-bottom:6px;'),
h('textarea', { value: neu.importText, rows: 5, style: WFELD + 'width:100%;font-family:var(--family-monospace,monospace);', onInput: (e) => { neu.importText = e.target.value; } }),